c++ 복사생성자

‍정진철·2022년 9월 9일
0

C++

목록 보기
10/18
post-thumbnail

잘못된 예시 (얕은 복사)

  • 해당 코드에서는 a의 주소값이 b의 주소값과 동일하게 되고 같은 값을 가르키케된다.

문제점 : a의 포인터 해제되지도 않았을 뿐더라 '5'의 값에 접근불가가 된다.

깊은 복사

  • a가 가르키는 공간이 b의 공간이 되게끔 만든다.

예시

#include <iostream>
using namespace std;

class String
{
public:
    String()
    {
        cout << "String() 생성자 호출" << endl;
        strData = NULL;
        len = 0;
    }
    String(const char *str)
    {
        cout << "String(const char *) 생성자 호출" << endl;
        len = strlen(str);
        strData = new char[len + 1];
        cout << "StrData 할당: " << (void *)strData << endl;
        strcpy(strData, str);
    }

    ~String()
    {
        cout << "~String() 소멸자 호출" << endl;
        delete[] strData;
        cout << "strData 해제됨: " << (void *)strData << endl;
        strData = NULL;
    }

    char *GetstrData() const
    {
        return strData;
    }

    int Getlen() const
    {
        return len;
    }

private:
    char *strData;
    int len;
};

int main()
{
    String s1("안녕");
    String s2(s1);
    
    cout << s1.GetstrData() << endl;
    cout << s2.GetstrData() << endl;
}
  • 객체 두개(s1,s2)를 생성했는데 ' 생성자 호출' 이 하나밖에 뜨지 않음.
  • 하지만 "안녕"은 2번에 걸쳐 출력되는걸로보아 '얕은복사'를 실행했음을 알 수 있음.


클래스 타입을 메개변수로 받는 복사생성자

#include <iostream>
using namespace std;

class String
{
public:
    String()
    {
        cout << "String() 생성자 호출" << endl;
        strData = NULL;
        len = 0;
    }
    String(const char *str)
    {
        cout << "String(const char *) 생성자 호출" << endl;
        len = strlen(str);
        strData = new char[len + 1];
        cout << "StrData 할당: " << (void *)strData << endl;
        strcpy(strData, str);
    }

    //매게변수로 String 클래스 타입을 받는것.
    String(const String &ref)
    {
        cout << "String(String &ref) 생성자 호출" << endl;
        strData = new char[ref.len + 1];
        cout << "strData 할당: " << (void *)strData << endl;
        strcpy(strData, ref.strData);
        len = ref.len;
        ;

        // len은 int타입이므로 애초에 서로 다른 메모리 공간상에 있는 객체. -> 깊은복사가 이루어짐.
        len = ref.len;
    }

    ~String()
    {
        cout << "~String() 소멸자 호출" << endl;
        delete[] strData;
        cout << "strData 해제됨: " << (void *)strData << endl;
        strData = NULL;
    }

    char *GetstrData() const
    {
        return strData;
    }

    int Getlen() const
    {
        return len;
    }

private:
    char *strData;
    int len;
};

int main()
{
    String s1("안녕");
    String s2(s1); //복사생성자

    cout << s1.GetstrData() << endl;
    cout << s2.GetstrData() << endl;
}

클래스 객체를 메개변수(ref)로 받는것.
따라서 해당 메개변수에 대한 주소값의 공간을 만들어 주는것.
깊은 복사를 위한것.

  • 생성자 호출도 2번
  • 복사생성자로 인한 '안녕' 출력 2번

profile
WILL is ALL

0개의 댓글