C++에서 구조체(struct)와 클래스(class)는 기본적으로 거의 동일한 기능을 제공합니다. 두 키워드 모두 멤버 변수와 멤버 함수를 가질 수 있고, 생성자·소멸자도 정의할 수 있습니다. 하지만 몇 가지 중요한 차이점이 존재하는데, 이를 이해하면 상황에 맞게 적절한 키워드를 선택할 수 있습니다.
1. 기본 접근 지정자(Default Access Specifier)의 차이
가장 큰 차이는 기본 접근 지정자입니다.
- 클래스의 멤버는 기본적으로 private입니다.
- 구조체의 멤버는 기본적으로 public입니다.
아래 두 코드를 비교해 보면 그 차이를 명확히 알 수 있습니다.
클래스 예제 — 컴파일 오류 발생
#include <iostream>
using namespace std;
class my_class {
int x = 10; // private 멤버
};
int main() {
my_class my_ob;
cout << my_ob.x; // 오류: private 멤버에 접근 불가
}출력 결과
컴파일되지 않습니다. private 데이터 멤버에 대한 컴파일 타임 에러가 발생합니다.
클래스에서는 접근 지정자를 명시하지 않으면 멤버가 자동으로 private으로 선언되기 때문에, 외부에서 x에 직접 접근할 수 없어 컴파일 오류가 발생합니다.
구조체 예제 — 정상 동작
#include <iostream>
using namespace std;
struct my_struct {
int x = 10; // public 멤버
};
int main() {
my_struct my_ob;
cout << my_ob.x;
}출력 결과
10
반면 구조체는 멤버가 기본적으로 public이므로 외부에서 자유롭게 접근할 수 있어 정상적으로 값이 출력됩니다.
2. 상속 시 기본 접근 지정자의 차이
두 번째 차이는 상속(Inheritance) 시 나타납니다.
- 구조체가 클래스나 다른 구조체로부터 상속받을 때, 기본 접근 지정자는 public입니다.
- 클래스가 상속될 때, 기본 접근 지정자는 private입니다.
클래스 상속 예제 — 컴파일 오류 발생
#include <iostream>
using namespace std;
class my_base_class {
public:
int x = 10;
};
class my_derived_class : my_base_class { // private 상속
};
int main() {
my_derived_class d;
cout << d.x; // 오류: 기반 클래스의 x에 접근 불가
}출력 결과
컴파일되지 않습니다. 기반 클래스의 변수 x에 접근할 수 없다는 컴파일 타임 에러가 발생합니다.
접근 지정자 없이 클래스를 상속하면 기본적으로 private 상속이 되므로, 기반 클래스의 public 멤버조차 파생 클래스 외부에서 접근할 수 없게 됩니다.
구조체 상속 예제 — 정상 동작
#include <iostream>
using namespace std;
class my_base_class {
public:
int x = 10;
};
struct my_derived_struct : my_base_class { // public 상속
};
int main() {
my_derived_struct d;
cout << d.x;
}출력 결과
10
구조체는 기본적으로 public 상속을 수행하기 때문에 기반 클래스의 멤버에 그대로 접근할 수 있습니다.
정리
| 구분 | 클래스(class) | 구조체(struct) |
|---|---|---|
| 멤버 기본 접근 지정자 | private | public |
| 상속 시 기본 접근 지정자 | private | public |
C++에서 구조체와 클래스의 기능적 차이는 이 두 가지뿐입니다. 따라서 데이터 위주의 단순한 묶음(POD, Plain Old Data)에는 구조체를, 캡슐화와 정보 은닉이 필요한 객체 지향 설계에는 클래스를 사용하는 것이 일반적인 관례이며, 코드의 의도를 더 명확하게 전달할 수 있습니다.