C++에서 컨테이너십(Containership)은 객체 지향 프로그래밍의 핵심 개념 중 하나로, 하나의 클래스가 다른 클래스의 객체를 멤버 변수로 포함하는 관계를 의미합니다. 이번 튜토리얼에서는 컨테이너십의 개념과 실제 코드 예제를 통해 그 동작 원리를 자세히 살펴보겠습니다.
컨테이너십이란?
어떤 클래스가 다른 클래스를 내부에 포함하고 있을 때, 이러한 관계를 컨테이너십이라고 부릅니다. 이때 각 클래스는 다음과 같이 구분됩니다.
- 포함된 클래스(Contained Class): 다른 클래스 내부에 존재하는 클래스
- 컨테이너 클래스(Container Class): 다른 클래스를 품고 있는 외부 클래스
이러한 구조는 'has-a' 관계라고도 불리며, 코드 재사용성을 높이고 모듈화된 설계를 가능하게 해줍니다.
예제 코드
아래 예제에서는 first 클래스가 포함된 클래스 역할을 하고, second 클래스가 컨테이너 클래스 역할을 합니다.
#include <iostream>
using namespace std;
class first {
public:
first() {
cout << "Hello from first class\n";
}
};
// 컨테이너 클래스
class second {
first f; // 포함된 클래스의 객체
public:
// 생성자
second() {
cout << "Hello from second class\n";
}
};
int main() {
second s;
return 0;
}실행 결과
Hello from first class Hello from second class
코드 분석
실행 결과를 보면 흥미로운 점을 발견할 수 있습니다. second 클래스의 객체 s가 생성되었을 뿐인데, first 클래스의 메시지가 먼저 출력되었습니다.
그 이유는 C++에서 멤버 객체는 컨테이너 클래스의 생성자 본문이 실행되기 전에 먼저 초기화되기 때문입니다. 즉, 객체 생성 순서는 다음과 같습니다.
second s;선언으로second객체 생성 시작- 멤버 변수인
first f의 기본 생성자가 먼저 호출됨 → "Hello from first class" 출력 - 이후
second클래스의 생성자 본문 실행 → "Hello from second class" 출력
마무리
컨테이너십은 상속(inheritance)과 함께 C++에서 클래스 간 관계를 표현하는 대표적인 방법입니다. 상속이 'is-a' 관계라면, 컨테이너십은 'has-a' 관계를 나타내며, 구성(Composition) 또는 위임(Delegation) 설계의 기반이 됩니다. 멤버 객체의 초기화 순서를 정확히 이해하면 생성자 동작을 예측 가능하게 만들 수 있어, 더 안정적이고 유지보수하기 좋은 코드를 작성할 수 있습니다.