初始化程序列表vs构造函数分配vs变量定义 [英] Initializer list vs Constructor assignment vs variable defining

查看:114
本文介绍了初始化程序列表vs构造函数分配vs变量定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to understand the real difference between the following Classes.

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变量的最佳方法?

Which one do you think is the best way to initialize width and height variables in a class?

我应该坚持一种方法吗?

Should I stick to one way over the others?

推荐答案

此摘录摘自Stanley B. Lippman的"Inside the C ++ Object Model".

This excerpt has been taken from "Inside the C++ Object Model" by Stanley B. Lippman.

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

You must use the member initialization list in the following cases in order for your program to compile:
1. When initializing a reference member
2. When initializing a const member
3. When invoking a base or member class constructor with a set of arguments
4. A few efficiency cases. (Here the program is correct w/o member initialization list)

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

For points 1-3, member initialization list is a must.
For point 4, it is not compulsory.

例如(点4),给定:

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

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

This implementation of the Word constructor initializes _name once, then overrides the initialization with an assignment, resulting in the creation and the destruction of a temporary String object.

本来可以编码出效率更高的实现方式:

A significantly more efficient implementation would have been coded:

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

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

Due to this optimisation, a lot of people prefer member initialization list, as a default approach to write constructors.

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

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

A reasonable question to ask at this point is, what actually happens to the member initialization list?

编译器遍历初始化列表,在所有显式用户代码之前按正确的顺序在构造函数中插入初始化.
例如,以前的Word构造函数扩展如下:

The compiler iterates over the initialization list, inserting the initializations in the proper order within the constructor prior to any explicit user code.
For example, the previous Word constructor is expanded as follows:

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

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

Note : The order in which the list entries are set down is determined by the declaration order of the members within the class declaration, not the order within the initialization list. In this case, _name is declared before _cnt in Word and so is placed first.

所以回到您的问题:

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

class B is fine(since you are using primitive datatypes).

class A将生成与class B

class C一样,首先调用默认构造函数,然后将进行widthheight的初始化.当要使用多个构造函数时,应该首选此方法,并且对于每个构造函数,widthheight需要默认设置为所需的值.

As for class C, the default constructor is first called, and then initialization of width and height would happen. This method should be preferred when there are going to be more than 1 constructor, and for each constructor width and height need to be defaulted to your desired values.

但是,由于C ++ 11的问世以及将{}用作统一初始化,因此编写class C的更推荐方法是:

However, since the advent of C++11, and use of {} as uniform initialization, a more recommended approach for writing class C would be :

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

这篇关于初始化程序列表vs构造函数分配vs变量定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆