생성자 및 소멸자 호출 스택
생성자
어떠한 객체가 생길때 호출 되는 함수
이때 변수 초기화같은 일들을 함
소멸자
어떠한 객체가 메모리에서 해제 될때 호출되는 함수
A 클래스 경우
코드
#include <iostream>
class A
{
static int a_Count;
public:
A()
{
a_Count++;
num = a_Count;
std::cout << num << "A생성자 호출\n";
}
~A()
{
a_Count--;
std::cout << num << "A소멸자 호출\n";
}
private:
int num = 0;
};
int A::a_Count = 0;
int main()
{
A a;
}
예상 출력값:
1A생성자 호출
1A소멸자 호출
실제 출력값:
1A생성자 호출
1A소멸자 호출
뭐 이건 당연한 이야기 같으니까 패스
A클래스를 맴버변수로 가지는 B클래스 경우
코드
#include <iostream>
class A
{
static int a_Count;
public:
A()
{
a_Count++;
num = a_Count;
std::cout << num << "A생성자 호출\n";
}
~A()
{
a_Count--;
std::cout << num << "A소멸자 호출\n";
}
private:
int num = 0;
};
class B
{
static int b_Count;
public:
B()
{
b_Count++;
num = b_Count;
std::cout << num << "B 생성자 호출\n";
}
~B()
{
b_Count--;
std::cout << num << "B 소멸자 호출\n";
}
// 테스트용 원래 이렇게 하면 안됨
private:
A a;
int num = 0;
};
int A::a_Count = 0;
int B::b_Count = 0;
int main()
{
B b;
}
예상 출력값:
1B생성자 호출
1A생성자 호출
1A소멸자 호출
1B소멸자 호출
실제 출력값:
1A생성자 호출
1B생성자 호출
1B소멸자 호출
1A소멸자 호출
생각한거의 딱 반대였음 일단 b가 호출이 되니까 B() 부터 호출 되는줄 알았는데 C++에서는 일단 안의 변수 부터 호출한다
좀 더 수정해 보자
수정 코드
#include <iostream>
class A
{
static int a_Count;
public:
A() : num(++a_Count)
{
std::cout << num << "A 생성자 실행\n";
std::cout << num << "A 생성자 호출\n";
}
~A()
{
std::cout << num << "A 소멸자 실행\n";
a_Count--;
std::cout << num << "A 소멸자 호출\n";
}
private:
int num = 0;
};
class B
{
static int b_Count;
public:
B() : num(++b_Count)
{
std::cout << num << "B 생성자 실행\n";
std::cout << num << "B 생성자 호출\n";
}
~B()
{
std::cout << num << "B 소멸자 실행\n";
b_Count--;
std::cout << num << "B 소멸자 호출\n";
}
// 테스트용 원래 이렇게 하면 안됨
private:
A a;
int num = 0;
};
int A::a_Count = 0;
int B::b_Count = 0;
int main()
{
B b;
}
결과값
1A 생성자 실행
1A 생성자 호출
1B 생성자 실행
1B 생성자 호출
1B 소멸자 실행
1B 소멸자 호출
1A 소멸자 실행
1A 소멸자 호출
일단 중단점 찍어서 확인해 보니까
- 생성자 순서
- b가 생성되는 순간
- a가 초기화 되면서 A()를 먼저 호출함
- a 생성자가 끝나고 나서 b를 초기화 하기 위해 B()를 호출함
- 소멸자
- b가 해제되는 순간
- 일단 ~B()를 호출
- 끝나고 나서 a를 해제 시키려고 ~A() 호출
결론 : 어떠한 클래스의 맴버변수를 클래스를 가지면 생성자가 호출할때 맴버변수가 초기화가 되면서 맴버변수 생성자부터 호출함
A클래스를 부모로 가지는 C클래스 경우
코드
#include <iostream>
class A
{
static int a_Count;
public:
A() : num(++a_Count)
{
std::cout << num << "A 생성자 실행\n";
std::cout << num << "A 생성자 호출\n";
}
~A()
{
std::cout << num << "A 소멸자 호출\n";
a_Count--;
std::cout << num << "A 소멸자 호출\n";
}
private:
int num = 0;
};
class C : public A
{
static int c_Count;
public:
C() : num(++c_Count)
{
std::cout << num << "C 생성자 실행\n";
std::cout << num << "C 생성자 호출\n";
}
~C()
{
std::cout << num << "C 소멸자 실행\n";
c_Count--;
std::cout << num << "C 소멸자 호출\n";
}
private:
int num = 0;
};
int A::a_Count = 0;
int C::c_Count = 0;
int main()
{
C c;
}
예상 출력값:
1C 생성자 실행
1C생성자 호출
1A 생성자 실행
1A생성자 호출
1A 소멸자 실행
1A소멸자 호출
1C 소멸자 실행
1C소멸자 호출
실제 출력값:
1A 생성자 실행
1A 생성자 호출
1C 생성자 실행
1C 생성자 호출
1C 소멸자 실행
1C 소멸자 호출
1A 소멸자 실행
1A 소멸자 호출
이것 또한 생각한거의 딱 반대였음 일단 c가 호출이 되니까 C() 부터 호출 되는줄 알았는데 C++에서는 코드상 보이지만 않을 뿐 자식 클래스 내부에 포함된 멤버변수처럼 동작함
중단점 찍어서 확인해본 결과
- 생성자 순서
- C클래스의 변수를 초기화 하려고 A클래스 생성자 호출
- A클래스 생성자 호출 후 C클래스 생성자 호출
- 소멸자 순서
- C클래스 소멸자 호출
- C클래스 소멸자 끝나기 전에 A클래스 소멸자 호출
- A클래스 소멸자 끝나고 나서 C클래스 소멸자가 끝남
결론 : 어떤 클래스를 상속받은 클래스는 부모 클래스를 맴버변수 취급을함, 자식 클래스가 생성자 호출을 하면 부모 클래스를 먼저 초기화 하려고 부모 클래스 생성자 부터 호출함