【问题标题】:Does C++ deep-initialize class members?C++ 是否深度初始化类成员?
【发布时间】:2009-02-05 06:38:55
【问题描述】:

我有一个具有以下成员的 C++ 类:

map< someEnum, vector<SomeObject*>* > someMap

所以我有一张地图,它为我拥有的每个枚举提供了一个对象向量。对于我的生活,我无法理解 C++ 是如何初始化这些对象的。默认情况下是否深度初始化它们?如果没有,我需要做什么?

无论我如何尝试这样做,我都会遇到分段错误(我已经尝试了一切),所以我猜我在概念上遗漏了一些东西。


我应该注意到我尝试使用:
map< someEnum, vector<SomeObject*> > someMap

同样如此,但效果不佳。在这种情况下,C++ 是否对向量进行深度初始化?

【问题讨论】:

  • 你能发布你是如何填充地图对象的吗?

标签: c++ data-structures oop


【解决方案1】:

规则是:如果 STL 容器包含指向对象的指针,它确实在堆上创建对象并将它们分配给这些指针。但是,如果它本身包含对象,它确实调用每个包含的对象的默认构造函数,从而初始化它们。

你这里有一个包含指针的映射(不管是什么类型的)。所以不要指望 map 让这些指针指向内存。

【讨论】:

    【解决方案2】:

    看起来地图为您提供了指向对象向量的指针。如果您尝试通过

    使用地图

    mymap[MY_ENUM]-&gt;push_back(whatever);

    在你初始化之前,你会得到一个段错误。你要么需要先初始化向量

    mymap[MY_ENUM] = new vector&lt;SomeObject*&gt;;

    或者,好多更好,只是让地图给你一个普通的 ol' 矢量

    map &lt;someEnum, vector&lt;SomeObject*&gt; &gt; mymap;

    当您第一次调用mymap[MY_ENUM] 时,向量将被默认初始化(大小为零)。问题是您在放大之前尝试使用向量的条目吗,例如,

    mymap[MY_ENUM][2] = whatever;

    你仍然需要使用push_backresize,或者给你一些空间的东西。

    【讨论】:

    • 杰西谢谢,我编辑了我的问题以回应你的回答。
    • mymap[MY_ENUM][2] = 不管;仍然不正确,在这种情况下,您将设置第三个 vector 实例。访问第三个元素的正确方法是 ( *mymap[MY_ENUM] )[2] = whatever;
    • @Tanveer:您提出的语法假设我们继续使用 map*>。但是 Jesse 建议改用更合理的 map >,在这种情况下 mymap[MY_ENUM][2] 确实是正确的语法。
    【解决方案3】:

    仅通过声明一个对象,您不会将 SomeObject 指针的向量很好地隐藏在该映射中。

    相反,您必须像这样继续:

    map< someEnum, vector< SomeObject* >* > someMap;
    
    someMap [ somevalue ] = new vector< SomeObject* >;
    
    someMap [ somevalue ] -> push_back( new SomeObject );
    

    你的痛苦不止于此。在地图超出范围之前,您需要正确清理它。

    // Untested code, may not even compile.
    for( map< someEnum, vector< SomeObject* >* >::iterator iter = someMap.begin( ) ; iter != someMap.end( ) ; ++i )
    {
         for( vector< SomeObject* >::iterator v = iter -> second -> begin( ) ; v != iter -> second -> end( ) ; ++v )
             delete *v;
    
         delete iter -> second;
    }
    

    【讨论】:

      【解决方案4】:

      你会得到一个空映射,它可以存储由 someEnum 引用的 std::vector*。空地图将不包含向量。由您来创建一个新的矢量对象(使用 new 是最安全的方式)并将其指针存储在地图中。

      这可能有点吹毛求疵,但如果枚举是固定(小)大小,那么为什么要为它们制作地图?除非您的人口稀少,否则一个简单的数组会更容易让您的面条四处走动,并且可能会提高空间和 CPU 效率。

      C++ 无法初始化地图或矢量的内容,因为它不知道要在那里存储什么。

      【讨论】:

      • 我认为这里的地图是个好主意,所以你有一个键索引向量。由于体积小,效率问题并不那么重要。
      • @Gorpik:Adam 的观点是,向量也可以用作“键索引向量”——事实上,它的运行速度更快并且使用的内存更少——前提是所有键都是小整数。跨度>
      • @j:只有在人口密集的情况下,即使在较小的集合中,空间效率也会更高。我从“枚举”中假设人口稠密且集合很小。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-18
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多