(Cโบโบ) ๐ชStrong pointer
Smart๊ฐ ์๋๋ผ Strong์ ๋๋ค
#include <stdio.h>
class RefBase
{
int mRefs;
public:
RefBase():mRefs(0){ printf("RefBase::RefBase()\n"); }
virtual ~RefBase(){ printf("RefBase::~RefBase()\n"); }
void incStrong() { mRefs++; }
void decStrong() { if( โmRefs == 0 ) delete this; }
};
template< typename T >
class sp
{
T *mPtr;
public:
sp(T *ptr) : mPtr(ptr) { mPtr->incStrong(); }
sp(const sp<T> &r) : mPtr(r.mPtr) { mPtr->incStrong(); }
~sp() {
mPtr->decStrong();
}
T *operator->() { return mPtr; }
T &operator*() { return *mPtr; }
};
class AAA : public RefBase
{
public:
AAA(){ printf("AAA::AAA()\n"); }
~AAA(){ printf("AAA::~AAA()\n"); }
void foo(){ printf("AAA::foo()\n"); }
};
int main()
{
sp<AAA> p1 = new AAA();
sp<AAA> p2 = p1;
return 0;
}
์๋๋ก์ด๋ ๋ค์ดํฐ๋ธ์์ ์ฌ์ฉํ๋ ์ค์ ์ฝ๋๋ ํจ์ฌ ๋ ๊ธธ๊ณ ๋ณต์กํ์ง๋ง ํต์ฌ๋ง ์ถ๋ฆฌ๋ฉด ์์ ์ฝ๋์ ๊ฐ๋ค. (์ค์ ์ฝ๋๋ ๋ฉํฐ์ฝ์ด ํ๊ฒฝ์ ๊ณ ๋ คํ์ฌ ์ฌ๋ฌ๊ฐ์ง atomic operation๋ ์ฌ์ฉ๋๊ณ ์ํผ ๋ณต์กํ๋ค)
๊ฐ๋
์ ์๋ Smart pointer
๊ฐ ์ ๋ช
ํด์ C++ ์ฝ๋๋ฅผ ์ด๋์ ๋ ์ฝ์ ์ ์๋ค๋ฉด ๋์์ ํ์
ํ ์ ์์ ๊ฒ์ด๋ค. ๊ทธ ์ ๋ช
ํ Effective C++์ ์ฒซ ์ฃผ์ ๊ฐ ๋ฐ๋ก RAII(Resource Acquisition Is Initialization)
์ธ๋ฐ ํฌ์ธํฐ๋ผ๋ ์์์ ๋ํด์ ๊ทธ๋ ๊ฒ ๊ตฌํํ๋ค๊ณ ๋ณด๋ฉด ๋ ๊ฑฐ๊ฐ๋ค.
์ฃผ๋ชฉํด์ ๋ณผ๋งํ ๋ถ๋ถ์ reference count
๋ฅผ sp
๊ฐ ๊ฐ์ง๊ณ ์์ง ์๊ณ pointing๋๋ ๊ฐ์ฒด๊ฐ ๊ฐ์ง๊ณ ์๋ค๋ ์ ์ด๋ค. ์๋ฅผ ๋ค์ด SP์์ static member variable์ ๊ฐ์ง๊ณ ์๋ค๋ฉด(๋ง๋ ์๋์ง๋ง) ์ฌ๋ฌ Smart pointer
๋ค์ด ์นด์ดํธ๋ฅผ ๊ณต์ ํด๋ฒ๋ฆด ๊ฒ์ด๋ค. ๊ทธ๋์ RefCount๋ฅผ ์์๋ฐ๋ ๊ฐ์ฒด
๋ง์ sp
๊ฐ ํฌ์ธํ
ํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ๋ค ์ํด ์ธํฐํ์ด์ค ๋ํ ๋น์ฐํ ์์ํ๋๋ฐ IncrementCount
์ DecrementCount
๊ฐ์ ๋์๋ค์ด ์ ๊ณต๋๋ค.
#include <stdio.h>
#include "StrongPointer.h"
#include "RefBase.h"
using namespace android;
class AAA : public RefBase
{
public:
AAA(){ printf("AAA::AAA()\n"); }
~AAA(){ printf("AAA::~AAA()\n"); }
void onFirstRef() { printf("onFirstRef()\n"); } // ๋ถ๋ชจ์ ์ธํฐํ์ด์ค๊ฐ virtual ํจ์์ด๋ค
void foo(){ printf("AAA::foo()\n"); }
};
int main()
{
sp<AAA> p1 = new AAA();
sp<AAA> p2 = p1;
return 0;
}
ํ๋ ๋ ์ดํด๋ณผ์ ์ onFirstRef()
ํจ์์ด๋ค. ๊ฐ์ํจ์์ด๊ธฐ ๋๋ฌธ์ RefBase๋ฅผ ์์๋ฐ๋๋ค๋ฉด ์๋์ผ๋ก ํธ์ถ๋๋ ๊ฐ์ํจ์์ด๋ค. ์ด ํจ์๋ ์ฒ์์ผ๋ก ์ค๋งํธํฌ์ธํฐ์ ๊ฐ์ด ํ ๋น๋ ๋ ํธ์ถ๋๋๋ฐ, ๊ทธ ์ด์ ๋ ์ข ๊ตฌ๋ฆฐ๊ฑฐ ๊ฐ๋ค.
AAA* p1 = new AAA()
์ ์ ๋ Smart pointer๋ฅผ ์์ฐ๊ณ ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฅ pointer๋ก ์ฌ์ฉํ ์๋ ์๋ ๊ฒ์ด๋ค. ์ด๊ฒ์ ์ปดํ์ผ์๋ฌ ๋ฑ์ผ๋ก ์ ์ดํ ์ ์๋คโฆ(์ ๋ง ์๋? ๊ตฌ๊ธ์ด ๋ชปํ์ผ๋ฉด ๋ชปํ๊ฑด๊ฐ)
๊ทธ๋์ ๊ฐ์ข ๋๋ฐ์ด์ค ๋ฑ ์ค์ํ ๊ฐ์ฒด์์ ์ค์ํ ์ด๊ธฐํ๋ ์์ฑ์๊ฐ ์๋๋ผ onFirstRef()์์ ํ๋๋ก ์ ์ฑ ์ ์ ํ๊ฒ์ด๋ค. Smart pointer๋ฅผ ์์ฐ๋ฉด ์๋๊ฒ๋. ์ข ์ด์ค๋ฝ์ง๋ง ์ด์ฉ๋ง ์ ์ผํ ๋ฐฉ๋ฒ์ผ์ง๋ ๋ชจ๋ฅธ๋ค.
#include <stdio.h>
#include "StrongPointer.h"
#include "RefBase.h"
using namespace android;
class AAA;
class BBB;
class AAA : public RefBase
{
public:
sp<BBB> pb;
AAA(){ printf("AAA::AAA()\n"); }
~AAA(){ printf("AAA::~AAA()\n"); }
void foo(){ printf("AAA::foo()\n"); }
};
class BBB : public RefBase
{
public:
sp<AAA> pa;
BBB(){ printf("BBB::BBB()\n"); }
~BBB(){ printf("BBB::~BBB()\n"); }
void foo(){ printf("AAA::foo()\n"); }
};
int main()
{
{
sp<AAA> p1 = new AAA();
sp<BBB> p2 = new BBB();
p1->pb = p2;
p2->pa = p1;
}
printf("step 1.\n");
return 0;
}
์ด๋ฒ์ sp
์ ์ํธ์ฐธ์กฐ ๋ฌธ์ ์ด๋ค.
์ ์์ ์ฒ๋ผ ๋ฉค๋ฒ์ธ Smart pointer
๊ฐ ์๋ก๋ฅผ ์ฐธ์กฐํ ๊ฒฝ์ฐ ์ ์๊ฐํด๋ณด๋ฉด, ๋ฉค๋ฒ์ ์ฐธ์กฐ๋ฅผ ํตํด์ ๊ฐ์ฒด์ RefCount๊ฐ 2๊ฐ ๋๋ฏ๋ก sp
๊ฐ Scope์์ ๋๊ฐ์ ์๋ฉธ๋๋๋ผ๋ RefCount
๋ 1์ด ๋๊ณ ๊ฐ์ฒด๋ ์๋ฉธ๋์ง ์๋๋ค. ์ด๊ฒ์ sp
๋ฟ๋ง ์๋๋ผ Smart pointer๋ฅ๊ฐ ๊ณตํต์ ์ผ๋ก ๊ฐ์ง๋ ๋ฌธ์ ์ด๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ๋ค์์ ์๊ฐํ wp ์ฆ, Weak pointer
๊ฐ ๋์
๋๋ค.