포함(Containment)
Containment는 상속이외의 클래스를 재활용할 수 있는 C++ 기법이다.
타 클래스의 객체를 멤버로 선언하여 해당 클래스의 기능을 사용하는 방식이다.
포함된 객체는 클래스가 아닌 멤버이므로 ObjectName(objectmemeber1,2,3)과 같은 형식으로 초기화한다.
예제코드는 다음과 같다.
#include <stdio.h>
#include <string.h>
#pragma warning(disable:4996)
class Date
{
protected:
int year, month, day;
public:
Date(int y, int m, int d) { year = y; month=m ; day = d; }
void OutDate() { printf("%d %d %d", year, month, day); }
};
class Book
{
private:
char name[64];
char author[64];
Date publicingDate; //Containment 'Date' Class
int price;
public :
// initialize list
// ** must write Containment Object's Default Constructor **
Book(const char* aname, const char* acompany, int y, int m, int d, int aprice) :
publicingDate(y, m, d) {
strcpy(name, aname);
strcpy(author, acompany);
price = aprice;
}
void OutBookInfo() {
printf("책이름:%s\n", name);
printf("작가:%s\n", author);
printf("출간일:");
publicingDate.OutDate();
printf("\n");
}
};
int main()
{
Book GameProgramming("Programming Unreal", "John Doran", 2020, 02, 25, 50000);
GameProgramming.OutBookInfo();
printf("\n");
Book HowToCplus("CplusExpert", "KimMunsung", 2020, 02, 24, 30000);
HowToCplus.OutBookInfo();
printf("\n");
GameProgramming.OutBookInfo();
}
보통 초기화 리스트에 '포함'된 객체의 초기화 생성자가 생략되면 디폴트 생성자를 호출하는데
'포함'된 객체는 디폴트 생성자가 없어 에러 처리되기에 유의해야한다.
사실 처음 포함을 공부할때 여러 객체들이 생성될 수 있는 클래스에 '단일 객체'가 멤버로 포함된다는 사실에 개인적으로 싱글톤 패턴이나, 정적 멤버처럼 포함'된' 객체를 포함'한' 클래스의 객체들이 공유해서 사용하는게 아닌가 싶었지만 Book 객체를 두개 생성해 출력해본 결과 객체의 value가 공유되는건 아니고 해당 객체의 클래스 구조만을 단순히 이용할 수 있는 기법이라는 점을 확인 할 수 있었다.
'포함'을 통해서는 클래스간의 Has A 관계를 표현할 수 있다.
Has A에 대한 전반적인 지식은 위키피디아를 참조해도 좋지만 구글 검색을 통해 간략하게 이해하기 쉬운 글을 찾았다.
Private 액세스 지정자를 이용한 상속의 경우에도 2차적인 상속을 금지시키며 Has A 관계를 표현할 수 있다. 두 기법의 가장 큰 차이점은 복수 개의 객체를 동시에 활용할 수 있는가의 여부이다. private 상속의 경우 같은 클래스를 두 번 상속할 수 없고 멤버 이름이 같아 복수 개의 정보를 동시에 표현할 수 없다, 따라서 클래스 작성에 두 개 이상의 객체의 활용이 필요하다면 포함(Containment)기법을 활용하는 것이 권장된다.
다만 포함'한' 클래스의 경우 포함'된' 클래스의 입장에서는 외부 클래스이므로 protected 멤버에 액세스 할 수 없다는 점 또한 유의해야한다.
'Language > C++' 카테고리의 다른 글
C++의 캐스팅 연산자 (0) | 2021.03.25 |
---|---|
템플릿 함수 사용시 유의사항 (0) | 2021.03.02 |
정적 멤버 변수, 함수 (0) | 2021.02.15 |
복사 생성자 사용시 유의할 점 (0) | 2021.02.15 |
int 변수의 앞자리가 0인 경우, 0123 = 83 ? Int prefix (0) | 2021.02.03 |