我试图了解以下两类之间的真正区别。
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;
};
您认为哪种方法是初始化类中的width
和height
变量的最佳方法?
我应该坚持一种方法吗?
答案 0 :(得分:1)
此摘录摘自Stanley B. Lippman的“ Inside the C ++ Object Model”。
在以下情况下,您必须使用成员初始化列表: 程序编译的顺序:
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
是 在_cnt
中的Word
之前声明,因此放在第一位。
所以回到您的问题:
class B
很好(因为您使用的是原始数据类型)。
class A
将生成与class B
相同的代码
对于class C
,首先调用默认构造函数,然后将初始化width
和height
。
当要使用多个构造函数时,应该首选此方法,并且对于每个构造函数width
和height
必须默认为所需的值。
但是,由于C ++ 11的问世以及使用{}
作为统一初始化,因此,编写class C
的更推荐方法是:
class C
{
public:
int width {500};
int height {300};
};