Post List

2017/12/18

C++__상속관계시 알아야할 것

상속관계시 알아야할 기본적인 내용에 대해서 간단히 적어보겠습니다.

1. 상속관계에서 생성자와 소멸자 호출 순서입니다.
상속관계에서 생성자 호출 순서는 부모 클래스의 생성자가 가장 먼저 호출이 되며,  마지막으로 자신 클래스의 생성자가 호출이 됩니다.
 - 부모 클래스 생성자 -> 자식 클래스 생성자

객체가 메모리에서 해제될때 호출되는 소멸자도 예외는 아닙니다.
소멸자는 생성자와 다르게 자신 클래스의 소멸자가 먼저 호출이되고 그 다음 부모 클래스의 소멸자가 호출이 됩니다.
 - 자식 클래스 소멸자 -> 부모 클래스 소멸자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Object
{
public:
    Object() {
        cout << "Object 생성자 호출" << endl;
    }
    virtual ~Object() { 
        cout << "Object 소멸자 호출" << endl;
    }
};
class Human : public Object
{
public:
    Human() {
        cout << "Human 생성자 호출" << endl;
    }
    ~Human() { 
        cout << "Human 소멸자 호출" << endl;
    }
};
class Woman : public Human
{
public:
    Woman() {
        cout << "Woman 생성자 호출" << endl;
    }
    ~Woman() {
        cout << "Woman 소멸자 호출" << endl;
    }
};
cs
Object > Human > Woman 의 상속관계를 가지는 클래스들이 있다고 했을때
Woman타입의 객체를 생성해보겠습니다.
1
2
3
4
5
6
7
int main()
{
    Object* pObject = new Woman;
    delete pObject;
cs

프로그램을 실행하면 ...

부모의 클래스의 생성자 부터 호출이 되며 마지막 자신 클래스의 생성자가 호출된게 보이실겁니다.
메모리 해제했을시에도 반대로 자신 클래스의 소멸자먼저 호출된 후 부모 클래스들의 소멸자가 순차적으로
호출된 부분도 확인하실 수 있습니다.

하지만 여기서 위 코드를 보면 소멸자앞에 virtual 키워드가 있습니다. virtual 키워드를 지우고 위 코드를
실행했을 때 생성자 호출부분은 동일하나 소멸자에서 Object의 소멸자만 호출이 되고 프로그램이 종료되었습니다.
여기서 포인터 타입을 Human으로 했다면 Object클래스와 Human클래스의 소멸자만 호출되고 종료될것입니다.

이처럼 상속관계에서 상속된 모든 타입의 클래스의 소멸자를 호출하기 위해선 virtual 키워드를 붙여주어야 하며,
소멸자 또한 자식 클래스에 오버라이딩된 함수라고 볼 수 있기 때문에 virtual 키워드를 붙여주지 않으면 포인터 타입의 객체를 삭제할때 포인터 타입의 객체의 소멸자만 호출이 됩니다.

여기서 의문이 들었습니다. 빈 클래스를 생성했을 때 객체의 크기는 얼마일까라는...
Human과 Woman 클래스를 주석걸고 Object타입의 객체를 생성하여, 사이즈를 얻어아 보았습니다.

네.. 사이즈 1이 나옵니다.. 
아무것도 들어 있지 않은 클래스를 생성할 경우 메모리의 크기는 1byte 객체를 생성했다는 것을 메모리공간에서 구분하기 위해 최소한의 바이트인 1byte를 할당한다고 합니다.