什么是C ++指针的默认构造函数?
我有这样的代码:
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]expression式是否将返回引用空指针,如果新项目添加到地图?
SGI文档说: data_type&operator [](const key_type&k)返回与特定键相关联的对象的引用。 如果地图尚未包含这样的对象,则operator []将插入默认对象data_type()。
所以,我的问题是插入默认对象data_type()是否会创build一个NULL指针,或者它可以创build一个无效的指针指向内存中的某个地方?
它会创build一个NULL
(0)指针,无论如何这是一个无效的指针:)
是的,它应该是一个零(空)指针,因为stl容器将默认初始化对象,当他们没有显式存储(即访问一个不存在的关键在一个地图,你正在做的或调整一个向量到一个更大的大小)。
C ++标准8.5中的第5段指出:
默认初始化Ttypes的对象意味着:
- 如果T是非POD类types(子句类),则调用T的默认构造函数(并且如果T没有可访问的默认构造函数,则初始化不合格)
- 如果T是一个数组types,每个元素都是默认初始化的
- 否则,对象的存储器将被初始化。
你还应该注意到,默认的初始化不同于简单的省略构造函数。 当你省略构造函数并简单地声明一个简单的types时,你会得到一个不确定的值。
int a; // not default constructed, will have random data int b = int(); // will be initialised to zero
更新:我完成了我的程序,我所问的那个线路有时会导致它崩溃,但是在稍后阶段。 问题是我创build一个新的对象,而不改变存储在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);
我很惊讶没有人注意到这一点。
expression式data_type()
计算为默认初始化的对象。 在非PODtypes的情况下,默认的构造函数被调用,但是在PODtypes的情况下,比如指针,默认的初始化相当于零初始化。
所以是的,你可以依靠你的地图创build一个NULL
指针。 为了解释,你可以参考伪构造器初始化器 。
不知道有关崩溃,但作为这种说法definetely内存泄漏
if(!mi)mi = new MapIndex();
总是返回true,因为指针mi并没有引用mapM为s的特定值而持有的东西。
我也会避免使用常规的指针,并使用boost :: shared_ptr或一些其他指针,销毁时释放内存。 这允许调用mapM.clear()或erase(),它应该调用存储在映射中的键和值的析构函数。 那么,如果这个值是POD(比如你的指针)那么就不会为此调用析构函数,除非手动删除,而迭代整个映射则会导致内存泄漏。