코가손의 블로그

C++ 깊은 복사 vs 얕은 복사 본문

C++/문법

C++ 깊은 복사 vs 얕은 복사

Cogason 2021. 11. 11. 09:36

깊은 복사

두 개의 값(인스턴스, 객체)이 생성됨

 

얕은 복사

원본은 하나, 두개의 포인터가 생성 됨

메모리 해제시 Double Free 문제 발생할 수 있음

 

class Data
{
public:
    Data(int param)
    {
        _data = new int;
        *_data = param;
    }
    
    ~Data()
    {
        delete _data;
    }
    
    int GetData()
    {
        return *_data;
    }
    
private:
    int* _data = nullptr;
};

int main()
{
    Data a = 10;
    Data b = a;
    
    cout << a.GetData() << endl;
    cout << b.GetData() << endl;
    
    return 0;
}

b가 a 를 얕은 복사를 한 상황

b의 소멸자가 Call 될 때, 에러가 발생한다.

'Data b = a'와 같은 코드가 실행 가능한 것은 Default 복사 생성자가 있기 때문인데

Default 복사 생성자는 a의 '_data'값을 가리키기 때문에 a의 소멸자가 호출되면 b는 이미 없는 메모리를 해제하려고

하기 때문에 에럭가 발생한다.

 

 

복사 생성자(깊은 복사)

Data(Data& other)
{
    _data = new int;
    *_data = *other._data;
}

따라서 얕은 복사 말고 깊은 복사를 하도록 생성자를 명시적으로 선언하여

b에게 a와는 다른 메모리를 할당받을 수 있도록 해야 한다.

 

복사 생성자와 복사 대입 연산자

Knight knight;

Knight knight2 = knight; // 복사 생성자

Knight knight3;
knight3 = knight;        // 복사 대입 연산자

클래스 생성시 기본적으로 복사 생성자와 복사 대입 연산자를 Default로 가지고 있다.

 

Knight(const Knight& knight)
{
    // 복사 생성자
}

Knight& operator=(const Knight& knight)
{
    // 복사 대입 연산자
}

복사 생성자와 복사 대입 연산자를 오버라이딩 하여 사용할 수 있다.

'C++ > 문법' 카테고리의 다른 글

C++ 객체 생성  (0) 2021.11.11
C++ 정적 바인딩 vs 동적 바인딩  (0) 2021.11.11
C++ static, extern  (0) 2021.11.09
컴파일 과정  (0) 2021.11.09
C++ 포인터 & 참조  (0) 2021.11.09
Comments