C++에서 구조체(struct)와 클래스(class)는 기본적으로 거의 동일한 기능을 제공합니다. 두 키워드 모두 멤버 변수와 멤버 함수를 가질 수 있으며, 생성자·소멸자 정의와 상속도 모두 가능합니다. 하지만 몇 가지 사소하면서도 중요한 차이점이 존재하는데, 이 글에서는 그 차이를 예제 코드와 함께 자세히 살펴보겠습니다.
1. 기본 접근 지정자의 차이
가장 핵심적인 차이는 기본(default) 접근 지정자입니다. 클래스의 멤버는 명시적으로 지정하지 않으면 기본적으로 private으로 설정되지만, 구조체의 멤버는 기본적으로 public으로 설정됩니다.
아래 두 예제 코드를 통해 이 차이를 직접 확인해 보겠습니다.
클래스 사용 예제 — 컴파일 오류 발생
#include <iostream>
using namespace std;
class my_class {
int x = 10;
};
int main() {
my_class my_ob;
cout << my_ob.x;
}
출력 결과
이 프로그램은 컴파일되지 않습니다.
x가 private 데이터 멤버이므로 외부에서 접근할 수 없어 컴파일 시간 오류가 발생합니다.
클래스 내부의 변수 x는 접근 지정자가 명시되지 않았기 때문에 기본값인 private으로 선언됩니다. 따라서 main 함수에서 외부로 접근하려고 하면 컴파일 오류가 발생합니다.
구조체 사용 예제 — 정상 동작
#include <iostream>
using namespace std;
struct my_struct {
int x = 10;
};
int main() {
my_struct my_ob;
cout << my_ob.x;
}
출력 결과
10
반면 구조체의 멤버는 기본적으로 public이므로, 별도의 접근 지정자 없이도 외부에서 자유롭게 접근할 수 있습니다.
2. 상속 시 기본 접근 지정자의 차이
상속 관계에서도 두 키워드의 차이가 나타납니다. 구조체가 다른 클래스나 구조체로부터 상속받을 때 기본 접근 방식은 public 상속이지만, 클래스가 상속받을 때의 기본 접근 방식은 private 상속입니다.
클래스 상속 예제 — 컴파일 오류 발생
#include <iostream>
using namespace std;
class my_base_class {
public:
int x = 10;
};
class my_derived_class : my_base_class {
};
int main() {
my_derived_class d;
cout << d.x;
}
출력 결과
이 프로그램은 컴파일되지 않습니다.
기본 클래스의 변수 x에 접근할 수 없다는 컴파일 시간 오류가 발생합니다.
상속 문법에서 접근 지정자를 생략했기 때문에 파생 클래스는 기본값인 private 상속을 받게 됩니다. 이 경우 기반 클래스의 public 멤버조차 파생 클래스 외부에서는 접근할 수 없게 됩니다.
구조체 상속 예제 — 정상 동작
#include <iostream>
using namespace std;
class my_base_class {
public:
int x = 10;
};
struct my_derived_struct : my_base_class {
};
int main() {
my_derived_struct d;
cout << d.x;
}
출력 결과
10
구조체는 기본적으로 public 상속을 받기 때문에, 기반 클래스의 public 멤버인 x에 그대로 접근할 수 있습니다.
정리
C++에서 구조체와 클래스의 차이를 요약하면 다음과 같습니다.
- 멤버의 기본 접근 지정자: 클래스는
private, 구조체는public - 상속 시 기본 접근 방식: 클래스는
private상속, 구조체는public상속
기능적인 관점에서 보면 두 키워드는 사실상 같지만, 일반적으로 C++에서는 데이터 위주의 단순한 자료 묶음에는 구조체를, 캡슐화와 정보 은닉이 필요한 객체 지향 설계에는 클래스를 사용하는 것이 좋은 코딩 스타일로 여겨집니다.