0

在我的代码中,我有一个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 ?

4

2 回答 2

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,p7

对 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 的整型常量表达式转换为指针类型会产生空指针值

于 2013-02-26T03:36:09.240 回答
2

是的,映射中用于 int 或指针等嵌入式类型的新元素是零初始化的,因此您的指针将为 NULL。

于 2013-02-26T03:24:56.720 回答