Language: C++ Toolkit: Qt4
The toolkit I'm using has a static method called int QEvent::registerEventType()
to register my own event types. When I subclass this QEvent
I need to supply the base class this value. QEvent::QEvent(int type)
.
Is it ok to use a static variable to call this before application starts? Consider the following:
//This is all in my .cpp file
static int myEventType; //This will contain my registered type
/*If I create a static instance of this class the constructor
gets called before the main() function starts.
*/
class DoRegisterMyEventType {
public:
DoRegisterMyEventType() {
myEventType = QEvent::registerEventType();
}
};
static DoRegisterMyEventType doRegisterMyEventType;
//Here is the constructor for MyEvent class which inherits QEvent.
MyEvent::MyEvent()
: QEvent(myEventType)
{
}
How 'evil' is this? I could wrap the whole thing in a namespace to prevent polluting the global namespace.
Static level initialization is a huge compiler-dependent grey area, as others have mentioned. However, function level initialization is not a grey area and can be used to your advantage.
static inline int GetMyEventType()
{
static int sEventType = QEvent::registerEventType();
return sEventType;
}
MyEvent::MyEvent()
: QEvent(GetMyEventType())
{
}
This solution has the property that registerEventType is guaranteed to be called before you need your event type even if you construct MyEvent during static initialization, which is good, but it does open you up to thread-safety issues if it's possible for MyEvent to be constructed on multiple threads.
Here's a thread-safe version, based on boost::call_once:
#include "boost/thread/once.hpp"
static boost::once_flag sHaveRegistered = BOOST_ONCE_INIT; //This is initialized statically, effectively at compile time.
static int sEventType = -1; //-1 is not a valid event
static void DoRegister()
{
sEventType = QEvent::registerEventType();
}
static inline int GetMyEventType()
{
boost::call_once(sHaveRegistered, &DoRegister);
return sEventType;
}