예전에 캐스팅하던 방법은 아래와 같다

 

 

//상속관계에 있는 두 클래스간의 상대적 거리값을 계산한다

//1 을 각 클래스* 로 캐스팅하여 빼면 두 클래스간의 포인터간 거리간격을 알 수 있고

//뺄셈으로 offset 을 알아낼 수 있다, 이것을 아래 thisPtr 에 더하면 thisPtr 에서부터 상대적으로

//offset만큼 떨어진곳(즉 자식)의 포인터를 알아낼 수 있게된다

int offset = (int)(T*)1 - (int)(Singleton_sjh<T>*)(T*)1;

 

//offset 이 int 이기때문에 _thisPtr 을 int 로 캐스팅해 더해줘야한다

//한 클래스에 여러개 클래스가 상속되면서 그때 싱글톤도 같이 상속될 경우 상속되는 것과 자식중 자식의

//주소로 싱글톤 포인터를 잡아줘야한다, 여러개 상속하면 주소가 자식의 주소가 아닌 다른 부모의 주소가 됨으로

//그냥 thisPtr 을 대입하면 Singleton_sjh 의 주소로 들어감으로 offset 을 더해 자식(T)의 주소 변환해줘야한다

 

_singleton=((T*)((int)_thisPtr + offset));

 

 

 

 

 

 

class aaa 

public:

int a;

aaa() : a(1)

{

}

 

void show()

{

std::cout<<"aaa"<<std::endl;

}

};

 

 

 

class ccc : public aaa, public Singleton_sjh<ccc>{

public:

int c;

ccc() : c(3)

{

  }

 

void show()

{

std::cout<<"ccc"<<std::endl;

}

};

 

int main(void)  

{  

//offset 을 강제로 0 을 대입하면  이레 show 함수 호출에서 오류가 난다는것을 알 수 있다

ccc::createInstanceWithAutoRelease();

ccc::GetinstanceSP()->show();

 

return 0;  

}  

 

 

 

 

 

 

하지만 현재는 static_cast 만으로도 캐스팅이 안전하게 된다

 

 

 

 

[주의해야하는 사항]

 

싱글톤을 상속받는 자식클래스는 싱글톤에서 자식을 템플릿 T 로 부르기때문에 자식의 생성자또한 헤더에 생성자가

기술되어있어야한다, 싱글톤이 템플릿임으로

그렇지 않을경우 얘기치 않은 메모리릭이나 오류가 발생할 수 있다, 스마트포인터로 싱글톤을 작성할때는 더더욱 이것을 지켜야한다

 

 

 


http://www.gpgstudy.com/forum/viewtopic.php?t=23728
 
 

해당 글의 원래 필자인 Scott Bilas가 자기 웹사이트에 이것과 관련해서 추가적으로 설명한게 있습니다. 

http://www.drizzle.com/~scottb/publish/gpgems1_singleton_notes.htm 

읽어보시면 아시겠지만 결론적으로 자신이 이 코드를 쓸 당시 Visual C++ 5를 사용한거 같은데 그 때는 간단한 캐스팅으로는 코드가 동작하지 않았다고 합니다. 

그래서 컴파일된 코드를 가지고 디어셈블링해서 저런 코드를 만들어 냈다고 하는군요. 당연히 이식성은 생각안했다고 합니다 . 어쨌든 결론은 지금은 그냥 static_cast을 써서 간단히 캐스팅해도 잘 된다는 것 입니다. 

코드:
Singleton( void )
{
  assert( !ms_Singleton );
  ms_Singleton = static_cast <T> (this);
}



이 답변은 GameDev에서 참고했습니다. 
http://www.gamedev.net/community/forums/topic.asp?topic_id=433262
_________________
Stay Hungry. Stay Foolish. 

 

 

반응형

+ Recent posts