class base_test
{
public:
base_test() { print(); }
void print() const {
cout << "나는 base_test" << endl;
}
};
class sub_test : public base_test
{
public:
sub_test() {}
void print ()const
{
cout << "나는 sub_test" << endl;
}
};
int _tmain()
{
sub_test t;
t.print();
}
이 코드를 실행시키면 어떤 순서로 출력을 얻을수 있을까?
정답은 "나는 base_test"->"나는 sub_test"순으로 출력값을 얻을수있다.
이제부터 상속시 class가 생성되는 순서를 알고있다는 가정하에서 글을 쓰겠다
A생성자에 print함수를 호출하면은 그 print함수는 A의 권한으로 print가 실행이되고 B생성자에서 호출하면 B의 print함수를 호출한다.
"나는 sub_test의 print를 불렀는데 왜 base_test의 print가 딸려오지?" 라고 생각하는가?
그 이유는 간단하다 base_test를 생성당시에는 sub_test는 초기화가 되어있지않아있기때문이다. 만약에 초기화가 되지않은 접근이 금지된 구역을 건드리면 미정의 동작을 하기때문에 좋지않은 결과가 나올것이 뻔하다.
해결방법은
class base_test
{
public:
base_test() { print(); }
void print() const {}
};
class sub_test : public base_test
{
public:
sub_test() : base_test() {}
void print ()const
{
cout << "나는 sub_test" << endl;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////
이런식으로 약간만 바꿔주면 된다
기본 클래스 부분이 생성될 때는 가상 함수를 호출한다고 해도 기본 클래스를 넘어갈수없기 때문에 필요한 초기화 정보를 파생 클래스 쪽에서 기본 클래스 생성자로 올려주도록 만든것이다
혹시나 이해가 안된다고 하면 한번더 말하겠다
생성자나 소멸자 그 안에서 실행되는것은 무엇이든간에 그 생성자나 소멸자의 클래스의 권한으로 모든것이 실행된다.
이것만은 잊지 말자!
*생성자 혹은 소멸자 안에서 가상함수를 호출하지 마라. 가상 함수라고 해도, 지금 실행중인 생성자나 소멸자에 해당되는 클래스의 파생 클래스 쪽으로는 내려가지않는다.
'IT책 > Effective c++' 카테고리의 다른 글
항목 10 : 대입연산자는 *this의 참조자를 반환하게 하자 (0) | 2019.06.21 |
---|---|
항목 8 : 예외가 소멸자를 떠나지 못하도록 붙들어 놓자 (0) | 2019.06.21 |
항목 7: 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자 (0) | 2019.06.20 |
4항목 : 객체를 사용하기 전에 반드시 그 객체를 초기화 하자 (0) | 2019.06.20 |
3항목: 낌새만 보이면 const를 들이대 보자 (0) | 2019.06.20 |