Object의 옳바른 복사
오브잭트를 복사를한다면 오브잭트의 내용을 복사한 사본이 필요하다
하지만 지금은 Object객체를 복사한다면 어떻게 될까?
Component 같은 경우는 원래의 주소를 가르키고 있는 오브잭트가 복사될 것 이다.
오브잭트의 주소값을 공유하고 있기 때문에 발생하는 현상이다.
04. Object -> CObject.h
...
public:
CObject();
//new
CObject(const CObject& _origin);
virtual ~CObject();
friend class CEventMgr;
};
04. Object -> CObject.cpp
...
CObject::CObject()
: m_vPos{}
, m_vScale{}
, m_pCollider(nullptr)
, m_bAlive(true)
{
}
//new
CObject::CObject(const CObject& _origin)
: m_strName(_origin.m_strName)
, m_vPos(_origin.m_vPos)
, m_vScale(_origin.m_vScale)
, m_pCollider(nullptr)
, m_bAlive(true)
{
m_pCollider = new CCollider(*_origin.m_pCollider);
m_pCollider->m_pOwner = this;
}
...
이렇게 하면 자동으로 컴파일러가 아래와 같이 생성해준다.
04. Object -> Player -> CPlayer.h
...
private:
void CreateMissile();
public:
CPlayer();
//exam: 부모쪽아 아래와 같은 복사 생성자가 자동으로 생성될 것이다.
CPlayer(const CPlayer& _origin)
: CObject(_origin)
, m_pTex(_origin.m_pTex)
{
}
~CPlayer();
};
씬에 새로운 객체를 한번 생성해보자면..
05. Scene -> Scene_Start -> CScene_Start.cpp
...
void CScene_Start::Enter()
{
CObject* pObj = new CPlayer;
pObj->SetPos(Vec2(640.f, 384.f));
pObj->SetScale(Vec2(100.f, 100.f));
AddObject(pObj, GROUP_TYPE::PLAYER);
//exam: 복사생성자로 플레이어를 한번더 만듬
CObject* pOtherPlayer = new CPlayer(*(CPlayer*)pObj);
pOtherPlayer->SetPos(Vec2(740.f, 384.f));
AddObject(pOtherPlayer, GROUP_TYPE::PLAYER);
...
}
...
복사생성자를 Clone으로 구현
04. Object -> CObject.h
"= 0" 을 써서 자식객체에서 구현하도록 강제한다.
...
public:
virtual void update() = 0;
virtual void finalupdate() final;
virtual void render(HDC _dc);
void component_render(HDC _dc);
//new: 자기 자신을 복사해서 되돌려주는 함수
virtual CObject* Clone() = 0;
...
04. Object -> Player -> CPlayer.h
자식 객체에서 클론 함수를 구현
...
private:
void CreateMissile();
//new
CPlayer* Clone() { return new CPlayer(*this); }
...
04. Object -> Monster -> CMonster.h
...
public:
virtual void update();
virtual void render(HDC _dc);
//new
CMonster* Clone() { return new CMonster(*this); }
...
05. Object -> Missile -> CMissile.h
미사일은 굳이 복사생성자를 해야할까..?
...
public:
virtual void OnCollisionEnter(CCollider* _pOther);
//new: 미사일은 얕은복사로도 될거같은데.. 굳이 복사생성자를..?
CMissile* Clone() { return new CMissile(*this); }
...
05. Scene -> Scene_Start -> CScene_Start.cpp
생성한 Clone 함수로 대체
...
void CScene_Start::Enter()
{
CObject* pObj = new CPlayer;
pObj->SetPos(Vec2(640.f, 384.f));
pObj->SetScale(Vec2(100.f, 100.f));
AddObject(pObj, GROUP_TYPE::PLAYER);
//old
//CObject* pOtherPlayer = new CPlayer(*(CPlayer*)pObj);
//new: pObj->Clone은 가상함수라 자식객체께 호출된다.
CObject* pOtherPlayer = pObj->Clone();
pOtherPlayer->SetPos(Vec2(740.f, 384.f));
AddObject(pOtherPlayer, GROUP_TYPE::PLAYER);
...
}
...
매크로로 모듈화
Clone이란 함수는 지금 무조건 구현하도록 강제되어 있다.
좀더 쉽게 구현하고자 한다면 매크로함수로 빼는것도 생각해보자
01. Header -> Define.h
...
#define fDT CTimeMgr::GetInst()->GetfDT()
#define DT CTimeMgr::GetInst()->GetDT()
//new
#define CLONE(type) type* Clone() {return new type(*this);}
...
04. Object -> Player -> CPlayer.h
...
private:
void CreateMissile();
//old
//CPlayer* Clone() { return new CPlayer(*this); }
//new
CLONE(CPlayer);
public:
CPlayer();
~CPlayer();
};
04. Object -> Monster -> CMonster.h
...
public:
virtual void update();
virtual void render(HDC _dc);
//old
//CMonster* Clone() { return new CMonster(*this); }
//new
CLONE(CMonster);
public:
CMonster();
~CMonster();
};
04. Object -> Missile-> CMissile.h
...
public:
virtual void OnCollisionEnter(CCollider* _pOther);
//old
//CMissile* Clone() { return new CMissile(*this); }
//new
CLONE(CMissile);
public:
CMissile();
~CMissile();
};