Uninitialized static data member of static class
我今天遇到了一个奇怪的问题,我不太明白。希望这里有人能帮忙。
设置相当简单。我有一个类,它有一个std::set类型的静态成员。该类有两个模板构造函数,它们只在参数数目上有所不同。这两个构造函数的行为相同,所以请注意,构造函数是模板化的,并且构造函数正在搜索并插入到std::set中。
我正在经历以下行为:对于类的静态实例,构造函数在静态std::set(find())上调用的第一个方法上崩溃。似乎该集未初始化。在我看来,在初始化静态成员变量之前调用了构造函数。
下面是一个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | ////////// Header File class ConVar : public IListener { friend EventHandler; // Event Handler auto registers all instances of convar to commands public: // Auto template< typename T > ConVar(string const& name, string const& description, T const& default_value ); private: static std::set<u32> mRegisteredVars; }; //////// INL file (included from header) template< typename T > ConVar::ConVar(string const& name, string const& description, T const& default_value ) : mName(name), mhName(name), mDescription(description), mClamp(false) { u32 hname = CONSTHASH(name.c_str()); ErrorIf(mRegisteredVars.find(hname) != mRegisteredVars.end(),"Attempt to create same ConVar multiple times. Note the ConVars are static singletons!"); *this = default_value; mRegisteredVars.insert(hname); gCore.Events.Subscribe(mhName, this); } ///////////// .cpp file std::set<u32> ConVar::mRegisteredVars; |
崩溃发生在find方法的errorif内部。如果我评论那行,它就会在插入的行上崩溃。
在main(类的静态实例)之前调用构造函数。有人知道这里会发生什么吗?
从构造函数访问彼此的全局对象在它们的声明顺序上会有问题。
有几种方法可以解决这个问题:
尝试
1 2 3 4 5 6 7 8 9 10 11 | //Change static std::set<u32> mRegisteredVars; //Into static std::set<u32>& getRegisteredVarsSet() { static std::set<u32>& mRegisteredVars; return mRegisteredVars; } // Obviously remove the `std::set<u32> ConVar::mRegisteredVars;` // From the cpp file. |
那么无论你在哪里使用:
现在,即使您从静态存储持续时间对象的构造函数访问
因为它是函数的静态成员,所以它的寿命是程序的长度,因此它将在调用之间保持其状态。
在调用
你的