This has been driving me crazy for a while. I've looked around the forums for an answer, but I haven't found any ... or if I have, I haven't been able to understand them.
Here's the deal, I have a template class that basically looks like this:
template< typename tThis >
class TGeometry : public CGeometry
{
public:
TGeometry( ) : CGeometry( GetClassID() ) { }
static const tClassID& GetClassID( )
{
static tClassID id = ms_GenerateClassID( );
return id;
}
};
where tClassID is a typedef for int and ms_GenerateClassID is a static method defined in CGeometry that generates a unique ID each time it's called. The idea behind this class is that it should allow me to create various types of geometry all with unique IDs. For each pair of geometry classes, I also make a TCollider< CGeom1, CGeom2 > which handles the specifics of collision detection between the two types. For each TCollider type, I make a static variable that does some registration stuff and, more importantly, calls TGeometry<??>::GetClassID( ) for both of the geometries the collider deals with.
The intention with this code is that ms_GenerateClassID( ) will only be called once for each geometry class. In debug mode, this is indeed the case. In release mode, however, ms_GenerateClassID( ) gets called once before main during the TCollider registration and once in main when I create the first instance of the geometry.
Rewriting the GetClassID( ) code in the following two ways makes it work as expected in release mode:
static const tClassID& GetClassID( )
{
static tClassID* id = new tClassID( ms_GenerateClassID( ) );
return *id;
}
static const tClassID& GetClassID( )
{
static bool b = true;
static tClassID id;
if( b ) { b = false; id = ms_GenerateClassID( ); }
return id;
}
My question is why? I believe I've heard people say you should allocate from the heap in this kind of situation, so I'm not too surprised that the first way works (though I don't really know why), but I'm pretty baffled that the second way works. It's seems like it's doing the exact same thing as the original code!
Well, I'd appreciate any insight into this mess,
Thanks,
John Edwards
p.s. I'm using MSVC6.