저는 프로그래밍 초보자이며 복사 생성자에 대해 배우고 있습니다. 다른 소스에서 클래스 객체를 "딥 복사 (deep copy)"하여 새로운 객체의 포인터 멤버가 새로운 메모리 위치를 가리 키도록하려는 경우 복사 생성자가 유용하다는 것을 알 수 있습니다.복사 생성자 및 동적 메모리
제 질문은, 빈 복사 생성자 (EmptyCat 클래스에서 사용)와 동일한 결과를 얻는 경우 CopyCat에서와 같이 복사 생성자를 정의하는 것의 이점은 무엇입니까?
두 번째 질문은 Cat 클래스와 EmptyCat 클래스가 다르게 작동하는 이유는 무엇입니까? 그들 사이의 유일한 차이점은 EmptyCat에 빈 복사 생성자를 정의한다는 것입니다. 그러나 프로그램을 실행하면 EmptyCat에서 포인터 멤버가 새 위치를 가리키는 것을 복사 한 후 Cat 클래스에서 얕은 복사본으로 작동한다는 것을 알 수 있습니다. 나는이 프로그램을 실행하면
#include "iostream"
class Cat
{
public:
void GetMem() { std::cout << itsAge << "\n"; }
private:
int * itsAge = new int;
};
class EmptyCat
{
public:
EmptyCat() {}
~EmptyCat() {}
EmptyCat(EmptyCat&obj) {}
void GetMem() { std::cout << itsAge << "\n"; }
private:
int * itsAge = new int;
};
class CopyCat
{
public:
CopyCat() {}
~CopyCat() {}
CopyCat(CopyCat&obj);
int GetAge() { return *itsAge; }
void GetMem() { std::cout << itsAge << "\n"; }
private:
int * itsAge = new int;
};
CopyCat::CopyCat(CopyCat & obj)
{
itsAge = new int;
*itsAge = obj.GetAge();
}
int main()
{
Cat Garfield;
Cat Kitty(Garfield);
std::cout << "Memory addresses for the objects' <itsAge> member:" << std::endl;
std::cout << "Garfield and Kitty (Class Cat):" << std::endl;
Garfield.GetMem();
Kitty.GetMem();
EmptyCat Meow;
EmptyCat Purr(Meow);
std::cout << std::endl << "Meow and Purr (Class EmptyCat):" << std::endl;
Meow.GetMem();
Purr.GetMem();
CopyCat Fluffy;
CopyCat Felix(Fluffy);
std::cout << std::endl << "Fluffy and Felix (Class CopyCat):" << std::endl;
Fluffy.GetMem();
Felix.GetMem();
system("pause");
return 0;
}
나는이 얻을 :
Memory addresses for the objects' <itsAge> member:
Garfield and Kitty (Class Cat):
00BBDA60
00BBDA60
Meow and Purr (Class EmptyCat):
00BB46A0
00BB8280
Fluffy and Felix (Class CopyCat):
00BB82B0
00BBE8A0
Press any key to continue . . .
클래스가 메모리를 누설하므로 실제로는 좋은 예제가 아닙니다. –
복사 생성자의 동작에 초점을 맞추어 가능한 한 간단하게 만들고 싶습니다. – SVG
그러나 그렇게함으로써 재미있는 모든 것을 놓치고 있습니다. 소멸자가 할당을 삭제해야한다면, 당신은 즉시 3 개의 모든 규칙을 발견 할 것입니다. –