본문으로 바로가기

컨테이너 상속에 대한

category C++/Before 2019. 2. 22. 15:13

컨테이너 ( vector, list, std::string .... ) 에 대한 상속은 금지되어 있다.

왜냐면 컨테이너는 가상 소멸자가 아니기 때문, 가상 소멸자로 선언하면 일반적으로 인스턴스를 만들어서 사용하는 컨테이너들은 오버헤드를 가지게 된다.

하지만 컨테이너를 상속받는 방법이 있는데, 소멸자를 새로 정의하지 않으면 된다.

 

클래스 멤버함수가 가상이 아니라는 것 = 이 클래스에 대해서 다형성을 적용하지 않겠다는 것

 

1. 추가 resource 를 할당해서, 소멸자가 이 resource 를 해제 해야하는 클래스만 아니라면 괜찮다.

 

2. built-in type ( int, double, bool .... 기본 자료형들 ) 멤버 변수를 더하는 것은 괜찮다.

 

3. 소멸자가 호출되지 않아도 괜찮은 ( resource 해제가 필요없는 ) 사용자 정의 타입 ( UDT ) 멤버 변수를 더하는 것도 괜찮다.

 

4. 소멸자가 호출되어야만 하는 ( resource 해제가 필요한 ) 사용자 정의 타입은 추가하면 안된다.

 

기본적으로 소멸자가 virtual 인 경우, 복사 생성자와 대입 연산자를 새로 재정의 해주어야 한다. ( 깊은 복사 )

 

class A : std::string {
public:
    A(int _t) : a(new int(_t)) {}
    ~A() { delete a; }

private:
    int* a;
    using std::string::basic_string;
};    // 1번 내용 ( error ) // 소멸자가 a resource 를 해제해야만 함

class B : std::string {
public:
    B(int _t) : a(_t) { }
    ~B() { }
private:
    using std::string::basic_string;
    int a;
};    // 2번 내용 ( ok ) 소멸자가 정의는 돼있지만 사용될 일은 없다. 멤버변수는 built in type

struct tempC {};
class C : std::string {
public:
    C() { }
    ~C() {}
private:
    using std::string::basic_string;
    tempC tc;
}; // 3번 내용 ( ok ) tc 는 사용자 정의 타입 ( UDT ) 지만 소멸자를 호출할 일이 없음

struct tempD {
    tempD(int _t) : d(new int(_t)) {};
    ~tempD() { delete d; }
    int* d;
};
class D : std::string {
public:
    D() {}
    ~D() {}
private:
    using std::string::basic_string;
    tempD td;
};    // 4번 내용 ( error ) td는 사용자 정의 타입 ( UDT ) 이고, 소멸자를 호출하여야만 함

'C++ > Before' 카테고리의 다른 글

SIMD Intrinsics  (0) 2022.01.04