[C++] 5-2. 깊은 복사와 얕은 복사

2024. 10. 31. 13:00·공부/C++
728x90

 생성자에서 동적 할당 -> 소멸자에서 해제 코드

                                    -> 복사 생성자 정의(깊은 복사) ->대입 연산자 오버로딩..


디폴트 복사 생성자는 멤버 대 멤버의 복수를 진행하며, 이를 '얕은 복사(shallow copy)'라 한다.

이는 멤버 변수가 힙의 메모리 공간을 참조하는 경우에 문제가 된다.

 

디폴트 복사 생성자의 문제점

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;

class Person {
private:
    char* name;
    int age;
public:
    Person(char* myname, int myage) {
        int len = strlen(myname) + 1;
        name = new char[len]; //new를 이용한 동적 할당
        strcpy(name, myname);
        age = myage;
    }
    void ShowPersonInfo() const {
        cout << "이름: " << name << endl;
        cout << "나이: " << name << endl;
    }
    ~Person() {
        delete[] name;//메모리 해제
        cout << "called destructor!" << endl;
    }
};

int main(void) {
    Person man1("Lee Dong woo", 29);
    Person man2 = man1;
    //디폴트 복사 생성자에 의한 멤버 대 멤버의 복사가 진행된다.
    man1.ShowPersonInfo();
    man2.ShowPersonInfo();
    return 0;
}

 

Person man2 = man1;

 

이 문장에서 디폴트 복사 생성자가 호출된다.

그러나 디폴트 복사 생성자는 멤버 대 멤버를 단순히 복사만 하므로,  하나의 문자열을 두 개의 객체가 동시에 참조하는 꼴을 만들어버린다.

따라서 객체의 소멸 과정에서 문제가 발생한다.

man2 객체가 먼저 소멸된다면, man2의 소멸자가 호출 된 이후에

man1의 소멸자가 실행되어야 하지만 man1의 name이 참조하는 문자열은 이미 소멸된 상태이다.

'깊은 복사'를 위한 복사 생성자의 정의

위 그림과 같은 형태로 복사가 되면, 객체 별로 각각의 문자열을 참조하기 때문에, 위에서 언급한 객체 소멸과정에서의 문제가 발생하지 않는다.

이렇게 멤버뿐만 아니라, 포인터로 참조하는 대상까지 깊게 복사하는 형태의 복사를 가리켜 '깊은 복사(deep copy)'라고 한다.

깊은 복사가 이뤄지도록 복사 생성자를 정의하면 다음과 같다.

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;

class Person
{
	char* name;
	int age;
public:
	Person(const char* myname, int myage)
	{
		int len = strlen(myname) + 1;
		name = new char[len];
		strcpy(name, myname);
		age = myage;
	}
	Person(const Person& copy)
		: age(copy.age)
	{
		name = new char[strlen(copy.name) + 1];
		strcpy(name, copy.name);
	}
	void ShowPersonInfo() const
	{
		cout << "이름: " << name << endl;
		cout << "나이: " << age << endl;
	}
	~Person()
	{
		delete[]name;
		cout << "called destructor!" << endl;
	}
};

int main(void)
{
	Person man1("Lee dong woo", 29);
	Person man2 = man1;
	man1.ShowPersonInfo();
	man2.ShowPersonInfo();
	return 0;
}

 

 

 

728x90

'공부 > C++' 카테고리의 다른 글

[C++] 6-1. const 보충  (0) 2024.10.31
[C++] 5-3. 복사생성자의 호출 시점  (0) 2024.10.31
[C++] 5-1. 복사 생성자  (0) 2024.10.30
[C++] 4-4. 클래스와 배열 그리고 this 포인터  (0) 2024.09.30
[C++] 4-2. 캡슐화(Encapsulation)  (0) 2024.09.23
'공부/C++' 카테고리의 다른 글
  • [C++] 6-1. const 보충
  • [C++] 5-3. 복사생성자의 호출 시점
  • [C++] 5-1. 복사 생성자
  • [C++] 4-4. 클래스와 배열 그리고 this 포인터
knhoo
knhoo
  • knhoo
    &*
    knhoo
  • 전체
    오늘
    어제
    • 전체 (142) N
      • Unity 개발일지 (1)
        • [Unity2D]졸업프로젝트 (17)
        • [Unity3D]VR프로젝트 (2)
      • 공부 (117) N
        • 부트캠프 (12)
        • C++ (39)
        • Unity & C# (8)
        • 데이터베이스 (2)
        • 컴퓨터비전 (0)
        • 컴퓨터구조 (0)
        • python (7)
        • BAEKJOON (38) N
        • 개발 (2)
        • 자료구조 (9)
      • 일상 (2)
  • 블로그 메뉴

    • Github
    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • 📖README
  • 인기 글

  • 태그

    Cpp
    Python
    오블완
    비트버니
    unity
    unity2d
    백준
    c#
    야핏무브
    머니워크
    구간합
    티스토리챌린지
    멋쟁이사자처럼후기
    패널파워
    앱테크
    자료구조
    til
    백준 #python
    C++
    캐시워크
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
knhoo
[C++] 5-2. 깊은 복사와 얕은 복사
상단으로

티스토리툴바