在我的代码中,我有std::map
看起来像这样:
std::map<std::string, A*> myMap;
其中A是我的一个自定义类。
当我通过operator[]
访问不存在的地图元素时,如下所示:
std::string s("hello");
A* pA = myMap[s];
我知道将使用该键创建一个新元素,但我希望将指针初始化为NULL。换句话说,如果存在myMap[s]
,则应返回有效指针。如果没有,我希望在上面的代码执行后pA为NULL。
默认情况下,如果myMap[s]
没有退出,pA是否会包含垃圾?如果元素不退出,我怎样才能使pA包含值NULL?
答案 0 :(得分:3)
简答:是的,在没有先前值的新密钥查找中,您的指针可以被可靠地视为nullptr
。
长答案:
按照标准:
C ++11§23.4.4.3,p5
T& operator[](key_type&& x);
效果:如果地图中没有等效于x的键,请将
value_type(std::move(x), T())
插入地图。
请特别注意使用 T()
,其中T
在这种情况下是您的指针类型。这导致......
C ++11§8.5,p10
一个对象,其初始化程序是一组空的括号,即(),应为值初始化。
通过值初始化的定义:
C ++11§8.5,第7页
对T类型的对象进行值初始化意味着:
如果T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T,初始化是错误的)没有可访问的默认构造函数);
如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化,如果T是隐式声明的默认值构造函数是非平凡的,该构造函数被调用。
如果T是数组类型,则每个元素都是值初始化的;
否则,该对象零初始化。
这使我们了解对象类型被零初始化的意义:
C ++11§8.5,p5
零初始化T类型的对象或引用意味着:
如果T是标量类型(3.9),则将对象设置为值0(零),作为整数常量表达式,转换为T (103) 强>
如果T是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都进行零初始化,并将填充初始化为零位;
如果T是(可能是cv限定的)联合类型,则对象的第一个非静态命名数据成员将进行零初始化,并将填充初始化为零位;
如果T是数组类型,则每个元素都是零初始化的;
如果T是引用类型,则不执行初始化。
103)如4.10中所述,将值为0的整型常量表达式转换为指针类型会产生空指针值。
答案 1 :(得分:2)
是嵌入式类型(如int或pointer)的map中的新元素是零初始化的,因此指针将为NULL。