Ordinarily, you can't cast a pointer to a member function of a derived class into a variable designed to hold a pointer to a member function of its base class -- in this case, the type "void (CBaseEntity::*)(void)" means "pointer to member function of CBaseEntity returning type void and taking no arguments", but the variable getting passed in most SetThink() calls is a pointer to a similar member function of a derived class like CBaseMonster or CBaseDoor. This language limitation exists because that sort of cast is an inherently unsafe operation under many circumstances. Fortunately, the Half-Life SDK isn't one of these, so Valve got away with it by forcing the conversion with static_cast. It's exactly what the comment says it is: an ugly, ugly hack. But it works, and it's a way around a problem which would otherwise be qutie irritating to solve.
I believe the debug version simply checks to make sure the function exists rather than assume it does and potentially crash, but I might be wrong as I'm just speaking offhand. ----- Original Message ----- From: "geoff c" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Thursday, December 19, 2002 7:26 PM Subject: [hlcoders] SetThink() [hard question #1] > These questions are intended to help me understand some of the more > important items in the server .DLL. > They're also intended to get some intelligent discussion going :) > > > How does SetThink() work? It's defined: > #define SetThink( a ) m_pfnThink = static_cast <void > (CBaseEntity::*)(void)> (a) > > With a comment above: > // Ugly technique to override base member functions > // Normally it's illegal to cast a pointer to a member function of a > derived class to a pointer to a > // member function of a base class. static_cast is a sleezy way around > that problem. > > Now I have no real formal training with C++, and that definition looks > really scary. Particularly the CBaseEntity::* > So for those of you _with_ formal training and/or brains, tell me, is this > a common procedure, or is it just a bit of genius on Valve's part? > > Bonus question: > #ifdef _DEBUG > #define SetThink( a ) ThinkSet( static_cast <void (CBaseEntity::*)(void)> > (a), #a ) > #else > > What's the difference for this debug version? > > > thanks. > --geoff > > _______________________________________________ > To unsubscribe, edit your list preferences, or view the list archives, please visit: > http://list.valvesoftware.com/mailman/listinfo/hlcoders > > > _______________________________________________ To unsubscribe, edit your list preferences, or view the list archives, please visit: http://list.valvesoftware.com/mailman/listinfo/hlcoders

