728x90
반응형
#include <iostream>
using namespace std;
class KTest
{
private:
int* pData;
int dataSize;
public:
KTest() : dataSize(3)
{
pData = new int[dataSize];
cout << "Constroctor" << endl;
}
void Release() { dataSize = 0; delete[] pData; }
~KTest()
{
Release();
cout << "Destroctor" << endl;
}
};
int main()
{
KTest k;
}
이 상태에서 시작해보자.
void Test(KTest t)
{
cout << "Test" << endl;
}
여기서 이 코드만 추가하고 실행시켜보면 크래쉬가 난다.
크래쉬가 나는 이유를 보기 위해서
소멸자의 Cout 코드를 Release 위로 올려보자
~KTest()
{
cout << "Destroctor" << endl;
Release();
}
생성자는 1번 소멸자는 2번 호출되는 모습을 볼 수 있다.
복사 생성자
우리에게 필요한건
Test함수로 값을 복사 시킬 때 호출될 생성자가 필요한것이다.
//복사 생성자
KTest(const KTest& rhs)
{
dataSize = rhs.dataSize;
pData = new int[dataSize];
memcpy(pData, rhs.pData, sizeof(int) * dataSize);
cout << "Copy Constroctor" << endl;
}
dataSize를 복사하고,
pData도 새롭게 동적할당해준다.
그리고 pData의 값을 그대로 가져와준다.
우리가 원하는대로 크래쉬가 안나고 잘 출력되는 것을 볼 수 있다.
복사생성자는 함수로 복사할 때 뿐만 아니라
이런 상황에서도 Copy Constroctor가 호출되는 것을 볼 수 있다.
동적으로 내부에서 데이터를 관리하고 있는 상황이라면 Copy Controctor 만들어줘야된다!
이것도 당연히 될 줄 알았겠지만, 2줄로 나눠서 코딩했을 뿐인데 크래쉬가 나는 모습을 볼 수 있다.
e=t 부분에서 e가 가르키는 pData 포인터와 t의 pData포인터가 일치되면서 생기는 버그이다.
void Release() {
dataSize = 0;
cout << pData << endl;
delete[] pData;
}
~KTest()
{
cout << "Destroctor" << endl;
Release();
}
주소를 출력해서 보면 소멸자에서 똑같은 주소를 2번 호출 하는 것을 볼 수 있다.
KTest& operator=(const KTest& rhs)
{
dataSize = rhs.dataSize;
pData = new int[dataSize];
memcpy(pData, rhs.pData, sizeof(int) * dataSize);
cout << "operator=()" << endl;
return *this;
}
이렇게 복사대입연산자를 통해서 새롭게 동적할당을 해주면서 버그를 피할 수 있다.
728x90
반응형
'C++' 카테고리의 다른 글
[C++] PerfectForwarding(4): move(2) (0) | 2024.11.20 |
---|---|
[C++] PerfectForwarding(4): move (0) | 2024.11.19 |
[C++] PerfectForward(2): l-value, r-value reference (0) | 2024.11.02 |
[C++] PerfectForwarding(1): l-value와 r-value (0) | 2024.11.01 |
[C++] virtual function( 생성자와 소멸자 ) (0) | 2024.10.31 |