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

Reply via email to