예전에 캐스팅하던 방법은 아래와 같다
//상속관계에 있는 두 클래스간의 상대적 거리값을 계산한다
//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 로 부르기때문에 자식의 생성자또한 헤더에 생성자가
기술되어있어야한다, 싱글톤이 템플릿임으로
그렇지 않을경우 얘기치 않은 메모리릭이나 오류가 발생할 수 있다, 스마트포인터로 싱글톤을 작성할때는 더더욱 이것을 지켜야한다
해당 글의 원래 필자인 Scott Bilas가 자기 웹사이트에 이것과 관련해서 추가적으로 설명한게 있습니다.
http://www.drizzle.com/~scottb/publish/gpgems1_singleton_notes.htm
읽어보시면 아시겠지만 결론적으로 자신이 이 코드를 쓸 당시 Visual C++ 5를 사용한거 같은데 그 때는 간단한 캐스팅으로는 코드가 동작하지 않았다고 합니다.
그래서 컴파일된 코드를 가지고 디어셈블링해서 저런 코드를 만들어 냈다고 하는군요. 당연히 이식성은 생각안했다고 합니다 . 어쨌든 결론은 지금은 그냥 static_cast을 써서 간단히 캐스팅해도 잘 된다는 것 입니다.
코드: | |||||
|
이 답변은 GameDev에서 참고했습니다.
http://www.gamedev.net/community/forums/topic.asp?topic_id=433262
_________________
Stay Hungry. Stay Foolish.
'디자인패턴과방법론 > 디자인패턴' 카테고리의 다른 글
게임 오브젝트 설계 #3 - 컴포넌트 기반 설계(component based) (0) | 2015.07.05 |
---|---|
Visual Studio를 통한 단위 테스트 자동화 (0) | 2013.04.24 |
visualstudio2010 의 UML (0) | 2012.11.02 |
아키텍처/프레임 워크/플랫 폼에 관한 정의 (0) | 2012.11.02 |
디자인 패턴 Why?, 그리고 목적 (0) | 2012.11.02 |