본문으로 건너뛰기
Previous
Next
C++ struct vs class | Access Control·POD

C++ struct vs class | Access Control·POD

C++ struct vs class | Access Control·POD

이 글의 핵심

C++ struct vs class difference is only default public/private, functionality is identical. Data grouping vs encapsulation convention, POD·C compatibility. Same syntax, compares intent expression and selection criteria.

Introduction

In C++, struct and class differ only in default access control, functionality is completely identical. To use an analogy, the syntactic difference is like whether to put a ‘public’ sticker on the meeting room door or ‘private’ is default, and what you can do inside the room (methods, inheritance, etc.) is the same. By convention, struct is often used for data grouping, class for objects maintaining invariants.

After Reading This

  • Understand the only difference between struct and class
  • Grasp usage rules and selection criteria
  • Check POD type and C compatibility
  • Learn selection strategy by practical scenario

Reality in Production

When learning development, everything is clean and theoretical. But production is different. You wrestle with legacy code, chase tight deadlines, and face unexpected bugs. The content covered in this guide was initially learned as theory, but I realized “ah, that’s why it’s designed this way” while applying it to actual projects. What stands out in my memory is the trial and error from my first project. I did it as I learned from books but spent days not knowing why it didn’t work. Eventually, I found the problem through a senior developer’s code review and learned a lot in the process. This guide covers not only theory but also pitfalls you may encounter in practice and their solutions.

Table of Contents

  1. struct vs class Difference
  2. Practical Implementation
  3. Advanced Usage
  4. Performance Comparison
  5. Practical Cases
  6. Troubleshooting
  7. Conclusion

struct vs class Difference

Only Difference: Default Access Control

Itemstructclass
Default access controlpublicprivate
Default inheritancepublicprivate
Constructor
Destructor
Member functions
Virtual functions
Inheritance
Templates

Practical Implementation

1) Basic Access Control

Here is detailed implementation code using C++. Import the necessary modules and define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

#include <iostream>
// struct: default public
struct Point {
    int x, y;  // public (default)
};
// class: default private
class Point2 {
    int x, y;  // private (default)
    
public:
    Point2(int x, int y) : x(x), y(y) {}
    
    int getX() const { return x; }
    int getY() const { return y; }
};
int main() {
    Point p;
    p.x = 10;  // ✅ OK
    p.y = 20;
    
    Point2 p2(10, 20);
    // p2.x = 10;  // ❌ Compile error: private member
    std::cout << p2.getX() << std::endl;
    
    return 0;
}

2) Inheritance Default Access Control

Here is detailed implementation code using C++. Import the necessary modules and define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

#include <iostream>
class Base {
public:
    void foo() {
        std::cout << "Base::foo" << std::endl;
    }
};
// struct: default public inheritance
struct DerivedStruct : Base {  // public inheritance
};
// class: default private inheritance
class DerivedClass : Base {  // private inheritance
};
int main() {
    DerivedStruct ds;
    ds.foo();  // ✅ OK (public inheritance)
    
    DerivedClass dc;
    // dc.foo();  // ❌ Compile error (private inheritance)
    
    return 0;
}

3) struct Can Be Used Like class

Here is detailed implementation code using C++. Import the necessary modules and define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

#include <iostream>
struct MyStruct {
private:  // Can specify private
    int x_;
    
public:
    MyStruct(int x) : x_(x) {
        std::cout << "Constructor: " << x_ << std::endl;
    }
    
    virtual void foo() {  // Virtual function
        std::cout << "MyStruct::foo: " << x_ << std::endl;
    }
    
    virtual ~MyStruct() {
        std::cout << "Destructor: " << x_ << std::endl;
    }
};
struct Derived : MyStruct {
    Derived(int x) : MyStruct(x) {}
    
    void foo() override {
        std::cout << "Derived::foo" << std::endl;
    }
};
int main() {
    MyStruct* p = new Derived(42);
    p->foo();  // Derived::foo
    delete p;
    
    return 0;
}

4) Usage Rules (Google C++ Style Guide)

struct: Passive Object Containing Only Data

Below is an implementation example using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

// ✅ Use struct
struct Point {
    int x, y;
};
struct Color {
    uint8_t r, g, b, a;
};
struct Config {
    std::string host;
    int port;
    bool useSSL;
};

class: Active Object with Encapsulation and Methods

Here is detailed implementation code using C++. Define a class to encapsulate data and functionality, and perform branching with conditionals. Understand the role of each part while examining the code.

// ✅ Use class
class BankAccount {
private:
    double balance_;
    
public:
    BankAccount(double initial) : balance_(initial) {}
    
    void deposit(double amount) {
        if (amount > 0) {
            balance_ += amount;
        }
    }
    
    void withdraw(double amount) {
        if (amount > 0 && balance_ >= amount) {
            balance_ -= amount;
        }
    }
    
    double getBalance() const {
        return balance_;
    }
};

Advanced Usage

1) POD Type

POD (Plain Old Data) is a simple type compatible with C. POD Conditions (C++11):

  • Trivial constructor
  • Trivial destructor
  • Trivial copy/move operators
  • Standard layout (no private/protected members, no virtual functions) Here is detailed implementation code using C++. Import the necessary modules and define a class to encapsulate data and functionality. Understand the role of each part while examining the code.
#include <iostream>
#include <type_traits>
// ✅ POD
struct Point {
    int x, y;
};
static_assert(std::is_pod_v<Point>);  // true
// ❌ Non-POD (has constructor)
struct Point2 {
    int x, y;
    Point2(int x, int y) : x(x), y(y) {}
};
static_assert(!std::is_pod_v<Point2>);  // false
int main() {
    std::cout << "Point is POD: " << std::is_pod_v<Point> << std::endl;
    std::cout << "Point2 is POD: " << std::is_pod_v<Point2> << std::endl;
    
    return 0;
}

Summary

Key Points

  1. struct vs class: Only default access control differs
  2. struct: For data grouping (default public)
  3. class: For encapsulation (default private)
  4. POD: Simple type compatible with C
  5. Convention: struct for data, class for objects

Decision Flowchart

Need encapsulation?
├─ Yes → class
└─ No (only data)
    └─ Need C compatibility?
        ├─ Yes → struct (POD)
        └─ No → struct (convention)

Best Practices

  • ✅ Use struct for data-only types
  • ✅ Use class for objects with behavior
  • ✅ Check POD for C compatibility
  • ❌ Don’t mix conventions
  • ❌ Don’t use struct for complex objects

  • C++ Aggregate Initialization
  • [C++ Memory Layout](/en/blog/go-series-03-oop-composition/
  • [C++ Object-Oriented Programming](/en/blog/go-series-03-oop-composition/ Master struct vs class selection! 🚀

자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. C++ struct vs class difference is only default public/private, functionality is identical. Data grouping vs encapsulatio… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


이 글에서 다루는 키워드 (관련 검색어)

C++, struct, class, access-control, POD, data-structure, OOP 등으로 검색하시면 이 글이 도움이 됩니다.