为什么我崩溃了这个静态地图? [英] Why am I crashing with this static map?

查看:71
本文介绍了为什么我崩溃了这个静态地图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在源文件中按字母顺序低于具有以下代码的文件时,为什么在使用DESERIALIZABLE_DEFINITION(CObject)时在DeserializableClassMapEntry()中崩溃?

使用预处理器宏是问题还是静态初始化失败?我的DeserializableClassMapEntry()是否在头文件中可以吗?

我可以通过以下方式解决此错误:将对象的宏按字母顺序放在父源文件中按字母顺序放在较低位置.我想这不会是可移植的.

所有这些代码都在使用它的所有类的基类的头文件中.静态映射deserializedObjectFunctionMap是在基类源或.cpp文件中定义的.

Why do I crash in DeserializableClassMapEntry() when using DESERIALIZABLE_DEFINITION( CObject ) in source files alphabetically lower than the file that has the following code and what is the proper way to fix it?

Is the problem from using the pre-processor macros or is this the static initialization fiasco? Is it OK that my DeserializableClassMapEntry() is in the header file?

I can fix this bug by putting the macro for objects lower alphabetically in a parent source file higher alphabetically. I would guess this would not be portable.

All of this code is in the header file of the base class for all of the classes that use it. The static map deserializedObjectFunctionMap is defined in the base class source, or .cpp file.

typedef void (*pReturnDeserializedObjectFunction)( std::istream & input, CDocElement ** ppEl );

typedef std::map< const CString, pReturnDeserializedObjectFunction > DeserializedObjectFunctionMap;


class DeserializableClassMapEntry
{
public:
    static DeserializedObjectFunctionMap deserializedObjectFunctionMap;
    DeserializableClassMapEntry( const char * classNameString, pReturnDeserializedObjectFunction returnDeserializedObjectFunction )
    {
        deserializedObjectFunctionMap[ classNameString ] = returnDeserializedObjectFunction;
    }
};

// the two macros
#define DESERIALIZABLE( classNameString )\
public:\
    static DeserializableClassMapEntry mapEntry;\
    static void DeserializeThis( std::istream & input, CDocElement ** ppElement );\


#define DESERIALIZABLE_DEFINITION( classNameString )\
    DeserializableClassMapEntry classNameString::mapEntry( #classNameString, &classNameString::DeserializeThis );\
    void classNameString::DeserializeThis( std::istream & input, CDocElement ** ppElement )\
    {\
        *ppElement = new classNameString;\
        input >> *(classNameString*)*ppElement;\
    };\           



更新:

因此,我要做的是将所有这些宏定义放在基类的.cpp文件中(按字母顺序排列的元素的定义低于该基类文件中包含静态功能图的元素的定义)定义.这样,由于它们位于同一文件(Eckel)中,因此我强制执行正确的初始化顺序.

关于此错误的一件困难的事是,静态函数映射看起来不错,即使它可能并非如此.但是有一个类最终将嵌入来自许多类的定义,这与我的观点背道而驰.这就是为什么我要等待一个好的答案.也许您会说我的选择很好,但是希望我能缺少一些东西.

感到奇怪的是,我从未说过新向量"之类的东西,因此首次使用惯用语" put-"new"静态函数返回引用没有似乎适合解决此问题.两者都没有消除静电.但是,如果仍然有我的嵌入式容器的修复程序,那就太好了.我会在这的.希望在很长一段时间内.



Update:

So what I''m going to do is put all those macro definitions in the .cpp file of the base class (the definitions for elements alphabetically lower than that base class file, which houses the static function map), after the static function map definition. That way I force correct initialization order because they are in the same file (Eckel).

One difficult thing about this bug was that the static function map looked like it was good, even though it probably wasn''t. But it goes against my grain to have a class that will end up embedding definitions from many classes. That''s why I will await a good answer. Maybe you will say my choice was good, but hopefully I''m missing something.

It was weird to realize I''ve never said anything like "new vector" and so the "first use idiom" put-"new"-static-in-a-fuction-and-return-a-reference didn''t seem to fit as a solution for this problem. Neither did taking out static-ness. But it would be great if there were still a fix for my embedded containers. I''ll be here. For a long time hopefully.

推荐答案

在同一翻译单元(源文件)中具有静态生存期的非本地对象将按照其定义的顺序进行初始化.翻译单位,不按字母顺序排列.反初始化以相反的顺序进行.跨翻译单元的初始化顺序是不确定的-即不依赖于源文件名的字典顺序或类似的东西.

如果我理解正确,那么您将依赖于这样的事实,即字母顺序较低"名称的文件中的非本地将在之前先初始化名称较大的源文件中的非本地.. !!请勿这样做,这将导致典型的静态订单初始化失败.一种可行的方法如下:

Non-local objects with static lifetime duration in the same translation unit (source file) are initialized in the order of their definition in that translation unit, not in alhphabetical order. The de-initialization occurs in reverse order. The initialization order across translation units is unspecified - i.e. does not depend on the lexicographic ordering of the source file names, or something like that.

If I understand correctly, you rely on the fact that non-locals in files with ''alphabetically lower'' names will be initialized before non-locals in source files with lexicoraphically larger names..?! Don''t do it, this will result in the typical static order initialization fiasco. One way to go would be the following:

class DeserializableClassMapEntry {
 private:

  static DeserializedObjectFunctionMap& GetObjectMap() {
   static DeserializedObjectFunctionMap sMap;
   return sMap;
  }
  
 public:

  DeserializableClassMapEntry( 
   const char * classNameString, 
   pReturnDeserializedObjectFunction returnDeserializedObjectFunction) {
  GetObjectMap()[ classNameString ] = returnDeserializedObjectFunction;
}

};



您可以使用类似的模式来适当地初始化mapEntry静态类对象.



You could yous a similar pattern for taking care of proper initialization of the mapEntry static class objects.


static void DeserializeThis( std::istream & input, CDocElement ** ppElement );\


此处的"\"是多余的.


The ''\'' here is redundant.


它将按定义顺序独立运行,如果您:(1)如上初始化映射,(2)注意用于您的注册服务商完全可以运行,(3)如果不考虑并发性,并且(4)您在DeserializableClassMapEntry对象之间没有任何进一步的依赖关系...使用dll和/或取决于结构可能会导致潜在问题您的程序.

在初始化阶段或反序列化期间(进入main之前或之后),程序是否崩溃(完全崩溃?)?您提到过.net,这里的背景是什么?还是您总体上询问这种设计?
It will work independently on definition order, if you: (1) initialize the map as above, (2) take care that the initializers for your registrars are run at all, (3) if concurrency is not considered and (4) you do not have any further dependencies among the DeserializableClassMapEntry objects... Potential issues could result from using dlls and/or depending on the structure of your program.

Is your program crashing (is it at all?) during the initialization phase, or during the deserializatio (before or after main is entered)? You mentioned .net, what is the context here? Or are you asking about this desing in general?


这篇关于为什么我崩溃了这个静态地图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆