我在静态初始化方面遇到了一些奇怪的问题。我正在使用代码生成器为我编写的消息传递系统生成结构和序列化代码。为了有一种方法可以根据消息 ID 轻松分配消息,我让我的代码生成器为每种消息类型输出类似于以下内容的内容:
MessageAllocator s_InputPushUserControllerMessageAlloc(INPUT_PUSH_USER_CONTROLLER_MESSAGE_ID, (AllocateMessageFunc)Create_InputPushUserControllerMessage);
MessageAllocator 类基本上是这样的:
MessageAllocator::MessageAllocator( uint32_t messageTypeID, AllocateMessageFunc func )
{
if (!s_map) s_map = new std::map<uint32_t, AllocateMessageFunc>();
if (s_map->insert(std::make_pair(messageTypeID, func)).second == false)
{
//duplicate key!
ASSERT(false, L"Nooooo!");
}
s_count++;
}
MessageAllocator::~MessageAllocator()
{
s_count--;
if (s_count == 0) delete s_map;
}
其中 s_
map 和 s_
count 是 MessageAllocator 的静态成员。这在大多数情况下都有效,但有时消息不会添加到 map 中。例如,除非我在启动代码中的某处调用 Create_
InputPushUserControllerMessage() ,否则不会添加此特定消息,但是其他消息可以正常工作。我认为这可能与链接器有关,错误地认为该类型未被引用并将其删除,因此我使用/OPT:NOREF 开关禁用了它(我使用的是 Visual Studio 2008 SP1),但这没有任何效果。
我知道“静态初始化顺序失败”的问题,但据我所知,这些对象的创建顺序不应改变结果,所以这对我来说似乎没问题。
如有任何见解,我们将不胜感激。
最佳答案
将static放入类中,使其成为类的静态成员
struct InputPushUserControllerMessageAlloc { static MessageAllocator s_obj; };
MessageAllocator InputPushUserControllerMessageAlloc::s_obj(
INPUT_PUSH_USER_CONTROLLER_MESSAGE_ID,
(AllocateMessageFunc)Create_InputPushUserControllerMessage);
标准允许它延迟具有命名空间范围的对象的初始化,直到使用其翻译单元中的任何函数/对象。如果初始化有副作用,则无法优化。但这并不禁止延迟它。
具有类作用域的对象并非如此。所以这可能会禁止它在那里优化某些东西。
关于c++ - 静态初始化的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/837088/