์คํํฌ๋ํํธ์์ ๋ ์ด์ค๋ผ๋ ์ ๋์ด ๋ค๋ฅธ ํ๊ฒ์ ๊ณต๊ฒฉํ๋ ์์
class Wraight
{
public :
int _hp = 150;
int _posX = 0;
int _posY = 0;
};
class Missile
{
public :
void SetTarget(Wraight* target)
{
_target = target;
}
void Update()
{
int posX = _target->_posX;
int posY = _target->_posY;
}
Wraight* _target = nullptr;
};
int main()
{
Wraight* wraight = new Wraight();
Missile* missile = new Missile();
missile->SetTarget(wraight);
wraight->_hp = 0;
delete wraight;
while (true)
{
if (missile)
{
missile->Update();
}
}
delete missile;
}
๋ ์ด์ค์ ๋ฏธ์ฌ์ผ์ด ํ๊ฒ์ ๋ฐ๋ผ๊ฐ๊ฒ๋ ๋ง๋ค ๊ฒ์ด๋ค.
๋ง์ฝ์ ๋ ์ด์ค๊ฐ ํผ๊ฒฉ์ ๋นํ์ฌ ๋ ์ด์ค๊ฐ delete๊ฐ ๋์ต๋๋ค.
์ด ๊ฒฝ์ฐ ๋ ์ด์ค ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์๋ ๋ฏธ์ฌ์ผ ๊ฐ์ฒด๋ null๊ฐ์ ๊ฐ์ง๊ฒ ๋๋ค.
์๋ช
์ฃผ๊ธฐ๋ฅผ ์๊ฐํ์ง ์๊ณ , ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ณ ์๋ ๋ค๋ฅธ ๊ฐ์ฒด๊ฐ ์์์๋ delete๋ฅผ ํด์ค ๊ฒ์ด ๋ฌธ์ ๊ฐ ๋๋ค.
RefCounting.h
#pragma once
/*--------------
RefCountable
---------------*/
class RefCountable
{
public:
RefCountable() : _refCount(1) { }
virtual ~RefCountable() { }
int32 GetRefCount() { return _refCount; }
int32 AddRef() { return ++_refCount; }
int32 ReleaseRef()
{
int32 refCount = --_refCount;
if (refCount == 0) {
delete(this);
}
return refCount;
}
protected:
int32 _refCount;
};
Main
#include "RefCounting.h"
class Wraight : public RefCountable
{
public :
int _hp = 150;
int _posX = 0;
int _posY = 0;
};
class Missile : public RefCountable
{
public :
void SetTarget(Wraight* target)
{
_target = target;
target->AddRef();
}
void Update()
{
if (_target == nullptr) return;
int posX = _target->_posX;
int posY = _target->_posY;
if (_target->_hp == 0)
{
_target->ReleaseRef();
_target = nullptr;
}
}
Wraight* _target = nullptr;
};
int main()
{
Wraight* wraight = new Wraight();
Missile* missile = new Missile();
missile->SetTarget(wraight);
wraight->_hp = 0;
wraight->ReleaseRef();
while (true)
{
if (missile)
{
missile->Update();
}
}
missile->ReleaseRef();
}
์์ ์ฝ๋๋ ํ์ฌ _refCount์ ๊ฐ์ด atomicํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ฉํฐ์ฐ๋ ๋ ํ๊ฒฝ์์ ๋ฌธ์ ๊ฐ ์๊ธด๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ atomic์ผ๋ก _refCount๋ฅผ ๋ฐ๊ฟ์ผ ํ๋ค. ์ด๋ ๊ฒ๋ง ํ๋ฉด ๋ ๊ฒ ๊ฐ์ง๋ง ์๋๋ค.
๊ทธ ์ด์ ๋ _refCount์ add ๋๋ releaseํ๋ ์ผ์ด atomicํ๊ฒ ์ด๋ฃจ์ด์ง์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ ๋ฏ ์๋์ผ๋ก add, release๋ฅผ ํ๋ ๊ฒ์ ์ข์ ๋ฐฉ๋ฒ์ด ์๋๊ณ , ์ค๋งํธํฌ์ธํฐ๋ฅผ ์ด์ฉํด์ ์๋์ผ๋ก ๊ด๋ฆฌ๋ฅผ ํ๋ ๊ฒ์ด ๋ฉํฐ์ฐ๋ ๋ํ๊ฒฝ์์ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
์ฝ๋ ์์์ ์ง์ ์ ์ผ๋ก(์๋์ ์ผ๋ก) add, release๋ฅผ ํด์ฃผ๋ ๊ฒ์ด ์๋๋ผ SharedPtr์์ ์๋์ ์ผ๋ก(null์ด ๋๋ฉด) ํด์ฃผ๊ฒ๋ ํ๋ ๊ฒ์ด ์ปจ์
์ด๋ค.
RefCounting.h
#pragma once
/*--------------
RefCountable
---------------*/
class RefCountable
{
public:
RefCountable() : _refCount(1) { }
virtual ~RefCountable() { }
int32 GetRefCount() { return _refCount; }
int32 AddRef() { return ++_refCount; }
int32 ReleaseRef()
{
int32 refCount = --_refCount;
if (refCount == 0) {
delete this;
}
return refCount;
}
protected:
atomic<int32> _refCount;
};
template<typename T>
class TSharedPtr
{
public:
TSharedPtr() { }
TSharedPtr(T* ptr) { Set(ptr); }
//๋ณต์ฌ
TSharedPtr(const TSharedPtr& rhs) { Set(rhs._ptr); }
//์ด๋
TSharedPtr(TSharedPtr&& rhs)
{
_ptr = rhs._ptr;
rhs._ptr = nullptr;
}
//์์ ๊ด๊ณ ๋ณต์ฌ
template<typename U>
TSharedPtr(const TSharedPtr<U>& rhs) { Set(static_cast<T*>(rhs._ptr)); }
~TSharedPtr() { Release(); }
public:
//๋ณต์ฌ ์ฐ์ฐ์
TSharedPtr& operator=(const TSharedPtr& rhs)
{
if (_ptr != rhs._ptr)
{
Release();
Set(rhs._ptr);
}
return *this;
}
//์ด๋ ์ฐ์ฐ์
TSharedPtr& operator=(TSharedPtr&& rhs)
{
Release();
_ptr = rhs._ptr;
rhs._ptr = nullptr;
return *this;
}
bool operator==(const TSharedPtr& rhs) const { return _ptr == rhs._ptr; }
bool operator==(T* ptr) const { return _ptr == ptr; }
bool operator!=(const TSharedPtr& rhs) const { return _ptr != rhs._ptr; }
bool operator!=(T* ptr) const { return _ptr != ptr; }
bool operator<(const TSharedPtr& rhs) const { return _ptr < rhs._ptr; }
T* operator*() const { return _ptr; }
const T* operator*() const { return _ptr; }
operator T* () const { return _ptr; }
T* operator->() { return _ptr; }
const T* operator->() const { return _ptr; }
bool isNull() { return _ptr == nullptr; }
private:
inline void Set(T* ptr)
{
_ptr = ptr;
if (ptr)
ptr->AddRef();
}
inline void Release()
{
if (_ptr != nullptr)
{
_ptr->ReleaseRef();
_ptr = nullptr;
}
}
private:
T* _ptr = nullptr;
};
Main
#include "pch.h"
#include <iostream>
#include "CorePch.h"
#include <atomic>
#include <mutex>
#include <windows.h>
#include <future>
#include "ThreadManager.h"
#include "RefCounting.h"
class Wraight : public RefCountable
{
public:
int _hp = 150;
int _posX = 0;
int _posY = 0;
};
using WraightRef = TSharedPtr<Wraight>;
class Missile : public RefCountable
{
public:
void SetTarget(WraightRef target)
{
_target = target;
// ์ค๊ฐ์ ๊ฐ์
๊ฐ๋ฅ
//target->AddRef();
}
bool Update()
{
if (_target == nullptr)
return true;
int posX = _target->_posX;
int posY = _target->_posY;
// TODO : ์ซ์๊ฐ๋ค
if (_target->_hp == 0)
{
//_target->ReleaseRef();
_target = nullptr;
return true;
}
return false;
}
WraightRef _target = nullptr;
};
using MissileRef = TSharedPtr<Missile>;
int main()
{
WraightRef wraight(new Wraight());
wraight->ReleaseRef();
MissileRef missile(new Missile());
missile->ReleaseRef();
missile->SetTarget(wraight);
// ๋ ์ด์ค๊ฐ ํผ๊ฒฉ ๋นํจ
wraight->_hp = 0;
//delete wraight;
//wraight->ReleaseRef();
wraight = nullptr;
while (true)
{
if (missile)
{
if (missile->Update())
{
//missile->ReleaseRef();
missile = nullptr;
}
}
}
//missile->ReleaseRef();
missile = nullptr;
//delete missile;
}