프로그래밍/C++

클래스의 복사

우대비 2022. 10. 22. 20:57
반응형
class Pet
{
public:
    Pet(){cout << "Pet()" << endl;}// 기본생성자
    Pet(const Pet& pet){cout << "Pet(const Pet&)" << endl;} //복사생성자
    ~Pet(){cout << "~Pet()" << endl;}

};

class Knight
{
public:
    Knight() {_pet = new Pet();} // 기본생성자
    Knight(const Knight& knight) {  } // 복사생성자
    ~Knight() {delete _pet;} 
    
public:
    int _hp = 100;
    Pet* _pet;
};


int main()
{
    Knight knight; // 기본 생성자
    knight._hp = 200;
    knight._pet = pet;
    
    Knight knight2 = knight; // 복사 생성자
    
    Knight knight3(knight);  //복사생성자
    
    Knight knight4; // 기본 생성자
    knight4 = knight; // 복사 대입 연산자
    
    return 0;
}

 

위의 코드에는 한가지 문제 있는데

knight2~4 까지의 객체가 knight 복사하면서 Pet 주소값까지 똑같이 복사하게 됨

똑같은 객체(Pet)에 delete 4 하게 된다는 얘기임..

 

위와 같은 문제는 컴파일러가 알잘딱 해주겠거니 생각하여

'복사 생성자, 복사 연산자'를 제대로 정의하지 않아서 발생하는데

위와같이 알잘딱 하여 정의해주면 문제는 발생하지 않음

class Pet
{
public:
	Pet()
	{
		cout << "Pet()" << endl;
	}
	~Pet()
	{
		cout << "~Pet()" << endl;
	}
	Pet(const Pet& pet)
	{
		cout << "Pet(const Pet&)" << endl;
	}
};


class Knight
{
public:
	Knight()
	{
		_pet = new Pet();
	}
	Knight(const Knight& knight)
	{
		_hp = knight._hp;
		_pet = new Pet(*(knight._pet));
	}
	
	Knight& operator=(const Knight& knight) // 복사 대입 연산자
	{
		_hp = knight._hp;
		_pet = new Pet(*(knight._pet));
		return *this;
	}

	~Knight()
	{
		delete _pet;
	}

public:
	int _hp = 100;
	Pet* _pet;
};

복사할때 'pet의 주소값'까지 복사되지 않게 '새로운 Pet'을 '복사 생성자로 생성'

 

반응형
LIST

'프로그래밍 > C++' 카테고리의 다른 글

캐스팅  (0) 2022.10.24
얕은 복사와 깊은 복사  (0) 2022.10.23
virtual 소멸자  (0) 2022.10.22
동적할당  (0) 2022.10.20
초기화 리스트  (0) 2022.10.18