공부중
[C++] 생성자 호출순서 다시 돌아보기 본문
이 제목을 뭐로 지을까 하다가 일단 이렇게 지어놓았다.
이 글은 상속이란 무엇이고 다형성이란 무엇이다라는 설명이 아니고
단순히 생성자 호출순서에 대한 내 실수를 다시 되짚고자 작성하는 글이므로
상속에대한 개념, 그리고 다형성이라는 개념을 찾으려고 들어오신 분들은 뒤로가기를 추천드립니다.
문제가 되었던것은 어제 출력결과를 묻는 특정 문제를 보게 되었다.
코드는 아래와 같다.
#include <iostream>
class AA
{
public:
AA() { std::cout << "A constructor" << std::endl; }
~AA() { std::cout << "A destructor" << std::endl; }
};
class BB : public AA
{
public:
BB() { std::cout << "B constructor" << std::endl; }
BB(int a) { std::cout << "B constructor int" << std::endl; }
~BB() { std::cout << "B destructor" << std::endl; }
};
int main()
{
BB bb(10);
return 0;
}
AA의 자식으로 BB가 있고 main에 있는것처럼 생성 할 때 어떠한 출력 결과가 나올것인가.
이거 입사 시험에서 은근히 비슷한 유형의 문제를 많이 봐서 나는 그만 실수를 저지르고 말았다.
음.. 일단 virtual이 소멸자에 없네? 그러면 정답은 이거지 하고 너무 짧게 생각해버렸다.
A constructor
B constructor int
A destructor
이렇게 나올것이라고 생각하고 집에와서 복기를 해보니 하.. 자세히 안본 멍청한 내 자신을 탓해야했다.
정답은 아래와 같다.
A constructor
B constructor int
B destructor
A destructor
BB의 형으로 bb의 객체를 생성했기에
BB의 부모인 AA의 생성자를 먼저 호출하고 그 다음 BB의 생성자를 호출하는데
param으로 int를 받고 있으므로 BB(int a) 생성자가 호출된다.
그리고 BB의 형으로 소멸자가 먼저 호출되고 그 다음 부모인 AA의 소멸자가 호출되어서 이런 출력결과가 나왔다.
아니 그러면 나는 도데체 어떤 코드랑 햇깔린것인가?
int main()
{
AA* bb = new BB(10);
delete bb;
return 0;
}
이 경우에는 AA의 형으로 BB의 객체를 담고있는 다형성을 보여주고 있다.
정말 간단하게 다형성이란, 기본 클래스(동물) 포인터로 파생 클래스(개,고양이, 기타 등등..) 객체를 관리하는것 이다.
이 경우에는 소멸자가 virtual이 아니면 내가 오답으로 적었던 아래의 출력 문구가 나오게 된다.
A constructor
B constructor int
A destructor
실제로 BB의 객체이지만 AA클래스 포인터를 기준으로 소멸자 호출을 하게 되는데 소멸자에 virtual이 붙어있지 않으므로 이 경우 자식이 있는지 알지 못하게 된다. 그러므로 소멸자 호출이 AA만 호출되게 된다.
그렇다면 main코드를 아래와 같이 바꾸면 어떻게 될것인가?
int main()
{
BB* bb = new BB(10);
delete bb;
return 0;
}
이 경우 포인터의 형과 생성하는 객체의 형이 서로 같으므로 다형성을 보여주지 않고 있으므로
BB의 소멸자는 AA의 소멸자도 호출하기 때문에 위에서 봤던 BB bb(10); 으로 생성하고 제거한것과 같은 출력결과를 보여준다.
A constructor
B constructor int
B destructor
A destructor
다음에는 좀 꼼꼼히 봐야할것 같다 -_-..
'Programing > C, C++' 카테고리의 다른 글
[C/C++] pthread 동기화에 관하여. (0) | 2024.12.10 |
---|---|
[C++] std::sort 사용시 invalid comparator가 발생한 경우. (0) | 2024.01.21 |
[VC++]권한이 필요한 프로세스를 생성할 경우. (0) | 2022.09.25 |
[C/C++] 배열 안에 자료형 크기가 다른 값으로 채우기 (0) | 2022.04.18 |
[MSVC]public 생성자를 만들었음에도 불구하고 링크에러가 나는 경우 (0) | 2021.05.24 |