int iOffset = (int)(type*)1 - (int)(CSingleton<type>*)(type*)1;
m_pSingleton = (type*)((int)this + iOffset);
:::Al:::
[Triple Buffer V2.0] - Resource leak imminent. Memory status: Fragile
int iOffset = (int)(type*)1 - (int)(CSingleton<type>*)(type*)1;
m_pSingleton = (type*)((int)this + iOffset);
quote:
Could you guys explain to me what this means exactly
quote:
thanks
// Copyright (C) Scott Bilas, 2000.
// All rights reserved worldwide.
#include <cassert>
template <typename T> class Singleton
{
static T* ms_Singleton;
public:
Singleton( void )
{
assert( !ms_Singleton );
int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
ms_Singleton = (T*)((int)this + offset);
}
virtual ~Singleton( void )
{ assert( ms_Singleton ); ms_Singleton = 0; }
static T& GetSingleton( void )
{ assert( ms_Singleton ); return ( *ms_Singleton ); }
static T* GetSingletonPtr( void )
{ return ( ms_Singleton ); }
};
template <typename T> T* Singleton <T>::ms_Singleton = 0;
static Base& getInstance() {
static std::auto_ptr<Base*> pInstance = new Child();
return *pInstance;
}
static Base& getInstance() {
static Base instance;
return instance;
}
quote:
Original post by civguy
Ok we all agree now that it's been used in various places and it's ugly, but can anyone throughoutly explain what's the meaning of that code?
quote:
what benefit does it give over simpler singleton accessors like these:
# include <cassert>
template <class object> class singleton
{
static object* p;
public:
singleton ()
{
assert (not p);
p = dynamic_cast <object*> (this);
assert (p);
}
virtual ~singleton ()
{
assert (p);
p = 0;
}
static object& instance () { assert (p); return *p; }
static object* instance_pointer () { return p; }
};
template <class object> object* singleton <object>::p = 0;
class something : public singleton <something> {};
int main ()
{
}
quote:
There...I cannot stand messy code.
#include <iostream.h>
#include <conio.h>
template <class type>
class CSingleton
{
private:
static type* m_pSingleton;
protected:
CSingleton()
{
int iOffset = (int)(type*)1 - (int)(CSingleton<type>*)(type*)1;
m_pSingleton = (type*)((int)this + iOffset);
}
public:
virtual ~CSingleton()
{
m_pSingleton = 0;
}
static type* GetPtr()
{
return m_pSingleton;
}
static type& GetVal()
{
return *m_pSingleton;
}
};
template <class type>
type* CSingleton<type>::m_pSingleton = 0;
class CTemp : public CSingleton<CTemp>
{
public:
CTemp()
{
x = 5;
}
~CTemp()
{
x = 0;
}
int GetX() { return x; }
void SetX( int num ) { x = num; }
private:
int x;
};
class CTemp2 : public CSingleton<CTemp2>
{
public:
CTemp2()
{
x = 0.5f;
}
~CTemp2()
{
x = 0.0;
}
float GetY() { return x; }
void SetY( float num ) { x = num; }
private:
float x;
};
void main()
{
CTemp* tmp = new CTemp;
cout<<tmp->GetX()<<endl;
tmp->SetX( 3 );
CTemp* tmp2 = CTemp::GetPtr();
cout<< tmp2->GetX()<< endl;
tmp2->SetX( 7 );
CTemp tmp3 = CTemp::GetVal();
cout<< tmp3.GetX()<< endl;
////////////////////////////////////////
CTemp2* p = new CTemp2;
cout<<p->GetY()<<endl;
p->SetY( 0.3f );
CTemp2* p2 = CTemp2::GetPtr();
cout<< p2->GetY()<< endl;
p2->SetY( 0.7 );
CTemp2 p3 = CTemp2::GetVal();
cout<< p3.GetY()<< endl;
cout<< tmp2->GetX()<< endl;
delete tmp;
delete p;
}
quote:
Hmm, at first it was starting to make sense but then it blurred again. Offset was 0 in all my tests, and I tried MI too, also with virtual base classes. When Singletonis constructed, the 'this' in it's constructor points to the memory where the object, i.e. T, is. So I can't see how a non-zero offset to the address could do any good.
quote:
Compiles fine. but it dosnt work.
// (insert my previous singleton example sans main ()...)
int main ()
{
something s; // assertion failed - p == 0 after dynamic_cast!
something::instance ();
}
quote:
Original post by null_pointer
Apparently it is impossible to use dynamic_cast to cast from a base class pointer to a derived class pointer[...]
// working code...
# include <cassert>
# include <ciso646> // Visual C++ 7.0- only
template <class object> class singleton
{
static object* p;
public:
singleton (object* pointer_to_object)
{
assert (not p);
this->p = pointer_to_object;
assert (p);
}
virtual ~singleton ()
{
assert (p);
p = 0;
}
static object& instance () { assert (p); return *p; }
static object* instance_pointer () { return p; }
};
template <class object> object* singleton <object>::p = 0;
class something : public singleton <something> { public: something () : singleton <something> (this) {} };
int main ()
{
something s;
something::instance ();
}
quote:
...when the derived class subpart of the object has not yet been constructed. I mentioned earlier in this thread that you can use static_cast. Try substituting that in for the dynamic_cast.
quote:
Original post by null_pointer
Hmm, seems like I am not the only "idiot" here.![]()
quote:
C++ Standard 5.2.9 para 5
An rvalue of type "pointer to cv1 B", where B is a class type, can be converted to an rvalue of type "pointer to cv2 D", where D is a class derived from B, if a valid standard conversion from "pointer to D" to "pointer to B" exists, cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is not a virtual base class of D.
This topic has been locked by a moderator. New replies are not allowed.
With your permission, GameDev.net uses analytics cookies to understand how people use the platform. You can accept analytics or continue with necessary cookies only. Learn more