Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 빈 클래스의 크기가 0이 아닌 이유는 무엇일까요?

C++에서 멤버 변수나 멤버 함수가 하나도 없는 빈 클래스를 정의했을 때, 그 크기가 과연 0일까요? 결론부터 말하면 그렇지 않습니다. C++ 표준은 크기가 0인 객체(또는 클래스)의 존재를 허용하지 않습니다. 만약 빈 클래스의 크기가 0이라면, 서로 다른 두 객체가 메모리상에서 동일한 위치를 가질 수 있게 되어 심각한 문제가 발생하기 때문입니다. 이러한 이유로 C++ 표준은 빈 클래스라도 최소한 1바이트의 크기를 갖도록 규정하고 있습니다. 일반적으로 빈 클래스의 크기는 1바이트입니다. 다음 예제를 통해 직접 확인해 보겠습니다.

예제

다음 코드를 실행하여 빈 클래스의 크기를 확인해 보겠습니다.

#include<iostream>
using namespace std;
class MyClass {
};
int main() {
    cout << sizeof(MyClass);
}

출력 결과

1

실행 결과를 보면 빈 클래스의 객체조차 최소 1바이트를 차지하는 것을 알 수 있습니다. 이는 서로 다른 두 객체가 반드시 서로 다른 메모리 주소를 가지도록 보장하기 위함입니다. 스택에 생성된 두 객체의 주소를 비교하는 아래 예제로 이를 확인할 수 있습니다.

예제

#include<iostream>
using namespace std;
class MyClass {
};
int main() {
    MyClass a, b;
    if (&a == &b)
        cout << "Same " << endl;
    else
        cout << "Not same " << endl;
}

출력 결과

Not same

두 객체 a와 b의 주소를 비교한 결과 "Not same"이 출력됩니다. 즉, 비어 있는 클래스라 하더라도 각 객체는 고유한 메모리 주소를 가지며, 이를 통해 객체 간의 구분이 가능해집니다.

동적 할당의 경우에도 마찬가지입니다. new 키워드로 생성한 객체 역시 같은 이유로 서로 다른 주소를 반환합니다.

예제 (C++)

#include<iostream>
using namespace std;
class MyClass {
};
int main() {
    MyClass *a = new MyClass();
    MyClass *b = new MyClass();
    if (a == b)
        cout << "Same " << endl;
    else
        cout << "Not same " << endl;
}

출력 결과

Not same

동적으로 할당된 두 객체의 포인터를 비교해도 서로 다른 주소임을 확인할 수 있습니다. 이처럼 new 연산자는 항상 고유한 메모리 공간을 할당하기 때문에, 두 포인터가 같은 값을 가질 수 없습니다.

참고: 빈 기본 클래스 최적화(EBO)

흥미로운 점은, 빈 클래스를 상속받아 사용하는 경우에는 컴파일러가 빈 기본 클래스 최적화(EBO, Empty Base Optimization)를 적용하여 파생 클래스의 크기에 추가 공간을 차지하지 않도록 할 수 있다는 것입니다. 즉, 독립적인 객체로 존재할 때는 최소 1바이트를 필요로 하지만, 기본 클래스로 활용될 때는 크기에 영향을 주지 않을 수 있습니다. 이러한 특성 때문에 std::less, std::allocator 같은 빈 클래스 기반의 유틸리티들이 표준 라이브러리에서 널리 활용됩니다.