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 |