생성자의 기본값과 해결 방법 복사

#include <iostream>
using namespace std;

class CTest
{
public:
    CTest() 
    {
        cout << "CTest()" << endl;
    }
    CTest(const CTest& rhs)
    {
        cout << "CTest(const CTest &)" << endl;
        //멤버값을 단순대입으로 복사
        this->m_nData = rhs.m_nData;
    }
    ~CTest() 
    {
        cout << "~CTest()" << endl;
    }

    int m_nData = 0;
};

int main()
{
    CTest a;
    a.m_nData = 300;

    CTest b(a);
    cout << a.m_nData << endl;
    cout << b.m_nData << endl;
}

기본적으로 위의 코드를 보면 복사 생성자 CTest b(a)가 정의되어 있으면 단순 대입으로 a의 요소 값을 간단히 복사한다.

그러나 이러한 코드는 심각한 오류를 유발합니다.

포인터가 사용될 때 포인터도 단순히 인스턴스 a의 멤버를 가리키므로 동적으로 할당한 후 삭제하면 당연히 오류가 발생합니다.

(이유 : 동적할당 후 Main Function Block 빠져 나올 때 기본적으로 소멸자 함수 부분에서 삭제가 이루어집니다.

이때 a가 가리키는 값이 삭제되면 b는 삭제된 값 a를 갖게 됩니다.

)

#include <iostream>
using namespace std;

class CTest
{
public:
    CTest()
    {
        cout << "CTest()" << endl;
        m_pData = new int(5);
    }
    CTest(const CTest& rhs)
    {
        cout << "CTest(const ctest &)" << endl;
        //인스턴스 b의 포인터 m_pData를 동적할당한 후,
        //동적할당한 int형 자료형에(*rhs.m_pData. 즉 여기선 a.m_nData)의 값을
        //복사하는 깊은 복사로 구현해야할 필요가 있다.

this->m_pData = new int(*rhs.m_pData); } ~CTest() { cout << "~CTest()" << endl; delete m_pData; } void SetData(int nParam) { *m_pData = nParam; } int GetData() { return *m_pData; } private: int *m_pData = nullptr; }; int main() { CTest a; CTest b(a); cout << a.GetData() << endl; cout << b.GetData() << endl; }

따라서 위와 같은 복사 생성자를 생성하는 경우 딥 카피로 코드를 구현해야 합니다.