C ++指针的默认构造函数是什么?

时间:2009-06-01 21:55:28

标签: c++ constructor map pointers

我有这样的代码:

class MapIndex
{
private:
    typedef std::map<std::string, MapIndex*> Container;
    Container mapM;

public:
    void add(std::list<std::string>& values)
    {
        if (values.empty()) // sanity check
            return;

        std::string s(*(values.begin()));
        values.erase(values.begin());
        if (values.empty())
            return;

        MapIndex *mi = mapM[s];  // <- question about this line
        if (!mi)
            mi = new MapIndex();
        mi->add(values);
    }
}

我主要担心的是,如果将新项添加到地图中,mapM [s]表达式是否会返回对NULL指针的引用?

SGI docs说: data_type&amp; operator [](const key_type&amp; k) 返回对与特定键关联的对象的引用。如果地图尚未包含此类对象,则operator []会插入默认对象data_type()。

所以,我的问题是默认对象data_type()的插入是否会创建一个NULL指针,或者它是否会创建指向内存中某处的无效指针?

5 个答案:

答案 0 :(得分:22)

它会创建一个NULL(0)指针,无论如何都是无效指针:)

答案 1 :(得分:18)

是的,它应该是一个零(NULL)指针,因为stl容器将默认初始化对象(如果没有显式存储)(即在执行时访问地图中不存在的键或将矢量调整为更大的尺寸) )。

C ++标准,8.5第5段规定:

  

默认初始化一个对象   类型T表示:

     
      
  • 如果T是非POD类类型(子类),则为默认值   调用T的构造函数(和   如果T有,则初始化是不正确的   没有可访问的默认构造函数)
  •   
  • 如果T是数组类型,则每个元素都是默认初始化的
  •   
  • 否则,对象的存储空间被初始化。
  •   

您还应该注意,默认初始化与简单地省略构造函数不同。省略构造函数并简单地声明一个简单类型时,您将获得一个不确定的值。

int a; // not default constructed, will have random data 
int b = int(); // will be initialised to zero

答案 2 :(得分:3)

更新:我完成了我的程序,我要问的那条线有时会导致它崩溃,但是在稍后阶段。问题是我正在创建一个新对象而不更改存储在std :: map中的指针。真正需要的是引用或指向该指针的指针。

MapIndex *mi = mapM[s];  // <- question about this line
if (!mi)
    mi = new MapIndex();
mi->add(values);

应更改为:

MapIndex* &mi = mapM[s];  // <- question about this line
if (!mi)
    mi = new MapIndex();
mi->add(values);

我很惊讶没有人注意到这一点。

答案 3 :(得分:2)

表达式data_type()计算为默认初始化对象。在非POD类型的情况下,调用默认构造函数,但是在POD类型的情况下,例如指针,默认初始化相当于零初始化。

所以是的,您可以依靠地图创建NULL指针。有关说明,请参阅Pseudo Constructor Initializers

答案 4 :(得分:0)

不确定崩溃,但定义内存泄漏如此声明

if(!mi)     mi = new MapIndex();

总是返回true,因为指针mi不是对mapM所持有的引用 对于s的特殊价值。

我也会避免使用常规指针并使用boost :: shared_ptr或其他 其他指针在销毁时释放内存。这允许调用mapM.clear()或erase() 应调用存储在地图中的键和值的析构函数。好吧,如果值是POD,例如指针,那么除非手动删除,否则不会为其调用析构函数 迭代整个地图会导致内存泄漏。