* 생성자 - 객체가 생성될때 호출되는 함수입니다.
* 소멸자 - 객체가 소멸될때 호출되는 함수입니다.
동적할당의 경우 delete에서 소멸자가 호출되고, 일반적인 객체 생성에서는 자동으로 소멸자가 호출됩니다.
자 아래와 같은 객체가 있다고 했을때 생성자와 소멸자가 없는데도 불구하고 객체는 생성, 대입 , 복사가 됩니다.
그 이유는 컴파일러가 디폴트 생성자와 디폴트 소멸자를 자동으로 생성하기 때문입니다.
즉 프로그래머가 만들지 않은 생성자와 호출자와 연산자를 컴파일러가 만들어주게 되는것 입니다.
[ 3번째 코드는 위 코드와 결국 같다.]
어떻게 생각해보면 참 편리한것 같습니다만...대표적으로 디폴트 복사 생성자에는 문제가 발생됩니다.
그 이유는 아래에서 확인할 수 있는데요.
[ 생성자는 순차적이나 소멸자는 순차적이지 않다...오히려 역순이다..]
처음 AA 객체 선언시 생성자에서 Name의 메모리가 할당됩니다.
이후에 객체 BB 선언시 디폴트 복사 생성자에서 메모리 할당 없이 객체 AA의 Name의 포인터만 복사하게 됩니다.(동적 할당된 공간을 복사하지 않고 가리키는 영역만 복사 *얕은 복사 문제)
BB 객체의 소멸자가 호출되어 Name 포인터가 가리키는 메모리는 해제가 되고, AA 소멸자가 호출되며, 역시 Name 포인터가 가리키는 메모리를 해제하려고 하여 발생하게 됩니다.
AA 소멸자가 Name 포인터가 가리키는 메모리를 해제하려고 했을때 이미 BB 객체의 소멸자에 의해 메모리 해제가 되어 버렸기 때문이죠..
결국 해당 문제를 해결하기 위해서는 복사 생성자를 프로그래머가 선언해주어야 합니다. (깊은 복사가 되도록)
[이제는 문제없이 잘 됩니다.]
기존에 동적 할당된 공간을 가리키는것이 아니라 동적 할당된 공간과 동일한 크기로 메모리 공간을 동적할당한 후에 공간을 가리켜 독립적인 메모리 공간을 가지게 되어 메모리 해제시에 오류가 발생하지 않습니다.
결국 복사 생성자를 프로그래머가 선언하지 않은 상태에서 자동으로 코드에 삽입되며, 얕은 복사 문제가 발생되기 때문에 동적할당에 의한 복사 생성이 필요한 경우 별도로 깊은 복사가 되도록 해야합니다.
'프로그래밍 > C++' 카테고리의 다른 글
[C/C++] 비트 연산과 시프트 연산 (0) | 2016.09.27 |
---|---|
[C++] 스마트 포인터 (0) | 2015.11.16 |
[ C++]연산자 오버로딩(1) - operator 키워드 (0) | 2015.10.20 |
[ C++]클래스 상속(4) - 순수 가상 함수 & 다중 상속 (0) | 2015.09.29 |
[ C++]클래스 상속(3) - 가상 함수 (0) | 2015.09.29 |