【问题标题】:mapped null pointer value [duplicate]映射的空指针值[重复]
【发布时间】:2013-02-26 03:15:28
【问题描述】:

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

【问题讨论】:

  • 如果在您调用之前密钥不存在,它将是一个 nullptr。这种生成的自动插入的映射值(在您的情况下为指针类型)是值初始化的,并且每个标准的值初始化指针是零初始化的,这与 nullptr 同义。 IE。你可以免费获得它。
  • 投票者愿意详细说明吗?我准确地解释了我想要实现的目标,并询问了有关在所提供情况下的默认行为的问题。
  • @user974967 这个问题没有显示任何研究工作(即您甚至没有尝试阅读手册)。
  • @melpomene 手册?那是什么手册?你是说标准吗?

标签: c++ map


【解决方案1】:

简短回答:是的,在没有先前值的新键查找中,您的指针可以可靠地被视为 nullptr

长答案:

按照标准:

C++11 § 23.4.4.3,p5

T&amp; operator[](key_type&amp;&amp; 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 的整型常量表达式转换为指针类型会导致 空指针值

【讨论】:

  • 感谢您回答问题和提供有用的信息。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    相关资源
    最近更新 更多