C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 강좌/문서
C++Builder Programming Tutorial&Docments
[205] boost 에서 자기 자신의 shared_ptr 리턴하기.
Lyn [tohnokanna] 22747 읽음    2010-03-01 15:05
boost 의 shared_ptr 은 편한 놈이지만..
문제가 생기는 상황이 몇 가지 있다 있다. 그 중 하나 바로 객체 내부에서 전역 함수(혹은 다른 class 의 함수)를 호출 할 때 this 를 넘기는 문제인데…

왜나면 아래와 같은 코드가 안되기 때문이다.
#include 
#include 

using namespace boost;

class SPtrTest;

void Func(shared_ptr sp);

class SPtrTest
{
public:
	int var1;
	SPtrTest()
	{
		printf("Constructor\n");
	}
	~SPtrTest()
	{
		printf("Destructor\n");
	}
	void operation()
	{
		
		Func(this);
	}
};

void Func(shared_ptr sp)
{
	sp->var1++;
	printf("%d\n", sp->var1);
};

int _tmain(int argc, _TCHAR* argv[])
{

	shared_ptr testclass(new SPtrTest);
	testclass->var1 = 0;
	testclass->operation();
		
	return 0;
}


shared_ptr과 포인터형은 서로 대입이 되지 않기 때문에 위와 같은 코드는 컴파일 에러를 뱉는다. 그럼 아래와 같이 고치면 어떨까.

#include 
#include 

using namespace boost;

class SPtrTest;

void Func(shared_ptr sp);

class SPtrTest
{
public:
	int var1;
	SPtrTest()
	{
		printf("Constructor\n");
	}
	~SPtrTest()
	{
		printf("Destructor\n");
	}
	void operation()
	{
		shared_ptr thisptr(this);
		Func(thisptr);
	}
};

void Func(shared_ptr sp)
{
	sp->var1++;
	printf("%d\n", sp->var1);
};

int _tmain(int argc, _TCHAR* argv[])
{

	shared_ptr testclass(new SPtrTest);
	testclass->var1 = 0;
	testclass->operation();
		
	return 0;
}

this 를 shared_ptr<SPtrTest> thisptr(this);
로 변환 해서 넘겻다.

이렇게 하면.
SPtrTest::Operation이 끝날때와 Func 가 끝날 때 2번 destructor 가 호출 되게 되어 에러가 난다.
이걸 방지하는 방법은 자기 자신의 shared_ptr 을 레퍼런스 카운트 문제가 생기지 않도록(this 를 넘길 때도 레퍼런스 카운터가 증가 하는) 하는 것이다.

즉 boost::enable_shared_from_this<T> 를 상속 받은 class 를 만드는 방법이다.
boost::enable_shared_from_this<T> 를 상속 받은 뒤 shared_from_this() 를 호출 하면 자기 자신의 shared_ptr 을 리턴 해 준다.

그럼 아래와 같이 된다
#include 
#include 
#include 

using namespace boost;

class SPtrTest;

void Func(shared_ptr sp);

class SPtrTest : public boost::enable_shared_from_this
{
public:
	int var1;
	SPtrTest()
	{
		printf("Constructor\n");
	}
	~SPtrTest()
	{
		printf("Destructor\n");
	}
	void operation()
	{
		Func(shared_from_this());
	}
};

void Func(shared_ptr sp)
{
	sp->var1++;
	printf("%d\n", sp->var1);
};

int _tmain(int argc, _TCHAR* argv[])
{

	shared_ptr testclass(new SPtrTest);
	testclass->var1 = 0;
	testclass->operation();
		
	return 0;
}


이렇게 하면 아무 문제 없이 작동이 가능하다.



Ps. 특히 조심해야 할 것은..
shared_ptr<SPtrTest> thisptr(this); 를 여러 번 생성 한다고 레퍼런스 카운터가 증가하는 것은 아니다. 레퍼런스 카운터의 증가는 변수끼리의 대입에 의해서만 증가할 뿐, 저런 선언은 카운터1짜리 변수를 여러 개 늘려 에러를 내게 할 뿐이다.

+ -

관련 글 리스트
205 boost 에서 자기 자신의 shared_ptr 리턴하기. Lyn 22747 2010/03/01
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.