- 얕은 복사란?
'복사 생성자'나 '복사 대입 연산자'를 통해 객체를 복사할 때, 멤버변수의 값을 그대로 복사하는 것을 얕은 복사라고 합니다.- 얕은 복사의 문제점
모든 멤버 변수를 값형으로 가지고 있다면 전혀 문제가 되지 않겠지만, pointer type의 멤버변수를 갖고 있다면 문제가 될 수 있습니다.(댕글링 포인터 등)
#include <iostream>
class weapon
{
public:
int Case = 0;// 0 = sword, 1 = gun
};
class fighter
{
public:
fighter(int _Att, int _Def, int _HP, weapon* Equip)
: Att(_Att), Def(_Def), HP(_HP), MyWeapon(Equip)
{
}
~fighter()
{
if (MyWeapon != nullptr)
{
delete MyWeapon;
}
}
//SwallowCopy
fighter(const fighter& Other)
{
Att = Other.Att;
Def = Other.Def;
HP = Other.HP;
MyWeapon = Other.MyWeapon;
}
int Att;
int Def;
int HP;
weapon* MyWeapon = nullptr; //컴포넌트로 해당 객체에 붙인 무기
};
int main()
{
weapon* AWeapon = new weapon;
AWeapon->Case = 0;
fighter A(10, 20, 30, AWeapon);
fighter B = A; //같은 무기 인스턴스를 사용하게 됨
//소멸자 호출 시 하나의 인스턴스를 두번 delete하게 되면서
//오류가 발생합니다
return 0;
}
얕은 복사의 한계를 해결하기 위해 깊은 복사를 고려할 수 있습니다.
- 깊은복사란?
pointer type의 멤버변수의 경우 새로운 메모리를 할당하고 그 안에 데이터를 복사하여 독립적인 인스턴스로 존재하게 하는 복사 방법.- 깊은 복사의 단점은?
메모리를 할당해야 하기 때문에 얕은 복사에 비해서 느리다는 단점이 있습니다. 깊은복사가 필요 없을 경우 비효율적인 방식입니다.
#include <iostream>
class weapon
{
public:
int Case = 0;// 0 = sword, 1 = gun
};
class fighter
{
public:
fighter(int _Att, int _Def, int _HP, weapon* Equip)
: Att(_Att), Def(_Def), HP(_HP), MyWeapon(Equip)
{
}
~fighter()
{
if (MyWeapon != nullptr)
{
delete MyWeapon;
}
}
//DeepCopy
fighter(const fighter& Other)
{
Att = Other.Att;
Def = Other.Def;
HP = Other.HP;
MyWeapon = new weapon;
*MyWeapon = *(Other.MyWeapon);
}
int Att;
int Def;
int HP;
weapon* MyWeapon = nullptr;
};
int main()
{
weapon* AWeapon = new weapon;
AWeapon->Case = 0;
fighter A(10, 20, 30, AWeapon);
fighter B = A;
return 0;
}