C++
깊은복사,얕은복사
Nin
2020. 12. 22. 14:58
class FightUnit
{
public:
int publincInt
public:
void Fight(FightUnit& _Other)
{
}
};
class Weapon
{
};
class Player : public FightUnit
{
private:
Weapon* pWeapon;
public:
Player() : pWeapon(new Weapon)
{
}
~Player()
{
if(nullptr != pWeapon)
{
delete pWeapon;
pWeapon = nullptr;
}
}
};
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); //릭 체크
Player NewPlayer = Player();
Player NewPlayer2 = Player(NewPlayer1); //복사 생성자
}
위의 코드는 에러가 나면서 실행이 중단된다.
이유는
int main()
{
int* p = new int();
delete p;
delete p;
}
이 코드와 같다.delete(메모리 해제)를 두번 하기때문이다.
메모리로 보면 이렇게 생각할 수 있고 pWeapon은
이름은 모르지만 힙 영역에 생긴 Weapon을 가리키고 연결되 있다.
Player(const Player& _Other) : pWeapon(_Other.pWeapon)
{
}
위의 코드에서 Player NewPlayer2 = Player(NewPlayer1); 이 코드는
위의 코드가 실행 된 것이고 이를 얕은 복사라고 한다.
가장 상단의 코드를 순서대로 생각해보면
NewPlayer1이 만들어지고 new를 이용해서 Weapon을 만든다.
그런 다음에 NewPlayer2가 만들어지고 NewPlayer2의 pWeapon은
NewPlayer1의 pWeapon이 가리키고 있는 얘를 똑같이 가르키고 있게된다.
메모리로 보면 이렇게 된다.
프로그램이 종료되면서 NewPlayer1이 사라지고 소멸자가 호출되면서
delete 호출되면서 힙영역의 Weapon을 메모리 해제하게된다.
그런다음에 NewPlayer2의 소멸자도 호출되면서 또 한번의 delete가 호출되면서
에러가 나게 되는것.
Player(const Player& _Other) : pWeapon(new Weapon(*_Other.pWeapon))
{
}
해결방법으로 위의 코드와 같이 새롭게 메모리를 할당해서 복사할 수 있고,
이를 깊은 복사라고 한다.
//얕은 복사
Player& operator = (const Player& _Other)
{
pWeapon = _Other.pWeapon;
}
//깊은 복사
Player& operator = (const Player& _Other)
{
pWeapon = new Weapon(*_Other.pWeapon);
}
대입 연산자의 복사 방식 코드.
얕은 복사와 깊은 복사는 상황에 따라서 알맞게 사용하면 되는 것이다.