【问题标题】:iterator default constructor and POD member initialization迭代器默认构造函数和POD成员初始化
【发布时间】:2011-11-11 01:34:27
【问题描述】:

来自 boost::iterator_facade 文档中的示例 [1]:

class node_iterator : public boost::iterator_facade< /* ... */ >
{
 public:  node_iterator() : m_node(0) { } 
          /* ... */
 private: node_base* m_node;
};

后跟脚注:

从技术上讲,C++ 标准对默认构造的迭代器几乎没有任何要求,因此如果我们真的关心效率,我们可以编写默认构造函数以使 m_node 未初始化。

我的问题(两部分):
(a) C++ 标准对默认构造的迭代器有什么要求?
(b) 为什么在实例化node_iterator 时省略m_node(0) 避免初始化m_node?无论如何,m_node 不会被默认初始化(因此是零初始化)吗?

[1]http://www.boost.org/doc/libs/1_47_0/libs/iterator/doc/iterator_facade.html#constructors-and-data-members (注:虽然这个问题源于一个 boost 示例,但我相信它适用于 STL 迭代器,因此我没有使用“boost”标签。)

【问题讨论】:

    标签: c++ iterator default-constructor


    【解决方案1】:

    为什么在实例化 node_iterator 时省略 m_node(0) 会避免初始化 m_node?

    仅仅因为 node_iterator 的默认构造函数被调用并不意味着类本身的非静态数据成员被正确初始化,尤其是在没有为这些数据成员指定初始化的情况下。这包括从构造函数初始化列表中省略那些非静态数据成员。此外,m_node 是一个指针,因此是 POD 类型,因此它没有默认构造函数,在进入 node_iterator 本身的构造函数主体之前将调用该构造函数来构造对象。因此,从初始化列表中省略 m_node 将避免专门初始化 m_node data_member。

    m_node 不会被默认初始化(因此是零初始化)吗?

    根据 C++03 规范第 8.5/9 节,如果未指定初始化器,则使用“不确定”值初始化非静态对象(还包括类的非静态数据成员)那个物体。非静态对象仅在它是非 POD 类类型和/或 const 限定类型时才被默认初始化。在这种情况下,m_node 是指针类型,因此是 POD 类型,因此它不是零初始化的……它只是用内存中变量位置的任何预先存在的值“初始化” ,从而使其成为初始化时使用的“不确定”值。

    【讨论】:

    • 谢谢!因此,要显式默认初始化非常量 POD 类型,我必须使用值初始化语法 m_node()?另外,对于我的问题的 (a) 部分,您在规范中有参考吗?
    • 是的,首选方法是在构造函数的初始化列表中使用值初始化语法。 C++11 还引入了其他一些可以初始化非静态成员的新方法。另一种选择是确保您在构造函数主体中设置变量的值,但这通常不是首选,因为初始化列表是在进入构造函数主体之前执行的,并且跳过初始化列表会丧失保证类的初始化状态在进入构造函数之前。
    猜你喜欢
    • 2016-04-05
    • 2011-08-09
    • 2015-06-21
    • 1970-01-01
    • 2015-07-03
    • 2018-11-24
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多