【问题标题】:Initializer list vs Constructor assignment vs variable defining [duplicate]初始化列表与构造函数赋值与变量定义[重复]
【发布时间】:2018-12-13 10:54:58
【问题描述】:

我试图了解以下类之间的真正区别。

class A
{
public:
    A()
    :width(500)
    ,height(300){};
    int width;
    int height;
};

class B
{
public:
    B()
    {
        width = 500;
        height = 300;
    };
    int width;
    int height;
};

class C
{
public:
    int width = 500;
    int height = 300;
};

您认为在一个类中初始化widthheight 变量的最佳方法是哪一个?

我应该坚持一种方式而不是其他方式吗?

【问题讨论】:

  • 使用A或者C。B是赋值,不是初始化,这和非原始成员和不能赋值的东西有很大区别。
  • 对于这个类,它们都是一样的;但是对于更复杂的类(特别是 - 数据成员不是原始类型),它们是不同的,如链接问题中所述
  • @M.M 这不是您提出的问题的重复,因为它不包括class C 之类的内容。
  • 好的。但是,当您询问人们的意见时,我投票决定以“主要基于意见”的方式结束。

标签: c++ class constructor initialization initializer-list


【解决方案1】:

此节选自 Stanley B. Lippman 的“C++ 对象模型内部”。

在下列情况下必须使用成员初始化列表 编译程序的顺序:
1. 初始化引用成员时
2. 初始化 const 成员时
3. 使用一组参数调用基类或成员类构造函数时
4.几个效率案例。 (这里的程序是正确的,没有成员初始化列表)

对于第 1-3 点,成员初始化列表是必须的。
对于第 4 点,这不是强制性的。

例如(第 4 点),给定:

class Word {
   String _name;
   int _cnt;
   public:
   // not wrong, just naive ...
   Word() {
      _name = 0;
      _cnt = 0;
   }
};

Word 构造函数的此实现将_name 初始化一次,然后用赋值覆盖初始化,从而创建和销毁临时String 对象。

一个更有效的实现将被编码:

// preferred implementation
Word::Word : _name( 0 )
{
    _cnt = 0;
}

由于这种优化,很多人更喜欢成员初始化列表,作为编写构造函数的默认方法。

// some insist on this coding style
Word::Word()
   : _cnt( 0 ), _name( 0 )
   {}

此时要问的一个合理问题是,成员初始化列表实际发生了什么

编译器遍历初始化列表,在任何显式用户代码之前以正确的顺序在构造函数中插入初始化。
比如前面的Word构造函数展开如下:

// Pseudo C++ Code
Word::Word( /* this pointer goes here */ )
{
   _name.String::String( 0 );
   _cnt = 0;
}

注意:列表条目的排列顺序已确定 通过类声明中成员的声明顺序, 不是初始化列表中的顺序。在这种情况下,_name 是 在Word 中的_cnt 之前声明,因此放在第一位。

所以回到你的问题:

class B 很好(因为您使用的是原始数据类型)。

class A 将生成与class B 相同的代码

对于class C,首先调用默认构造函数,然后初始化widthheight。当有多个构造函数时应该首选此方法,并且对于每个构造函数 widthheight 需要默认为您想要的值。

然而,自从 C++11 出现,并使用 {} 作为统一初始化,更推荐的编写 class C 的方法是:

class C
{
    public:
    int width {500};
    int height {300};
};

【讨论】:

  • 我相信这是比链接线程更好的答案。
猜你喜欢
  • 2014-03-21
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
相关资源
最近更新 更多