很多人可能没有注意到,都写成第一种办法的样子,如果有人问我第一种办法可以吗?当然可以,但是效率比较差一些,不够“大气”。

(c++构造函数的概念以及作用本文不简述,具体的概念及作用可以自行百度,请谅解)
先放出一段类的定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
class complex
{
public:
//需要重点讨论的构造函数
complex (double r= 0, double i = 0)
{ re = r; im = i; }
complex& operator += (const compl&);
double real () const { return re; }
double imag () const { return im; }
private:
double re, im;
friend complex& _doapl (complex*, const complex&);
}

然后我们重点在以下的构造函数
1
2
complex (double  r= 0, double i = 0)
{ re = r; im = i; }

可以看出该构造函数初始化了re和im的值,这是一种初始化办法,然后我们还有另一种比较“大气”的办法:
1
2
3
complex (double  r= 0, double i = 0)
: re (r), im (i) //初始化列,冒号后面的就是初始化列表
{ }

两者办法实现的效果都一样的,都是用r初始化re,用i初始化im,但是两者有什么区别呢?

  1. 第二种办法利用了构造函数很特别的语法(只有构造函数才有),就是第二行初始化re,im值的办法
  2. 第二种办法效率更高
    因为对于一个对象,其数值的设定有两个阶段:一个是初始化,一个是后面的赋值操作,而初始化列表就是在初始阶段。第二种办法在初始化列已经完成了两种操作,虽然第一种办法在大括号里面也完成了这两种操作,但是结果相同过程不同,第二种办法快一点。

那么两者该如何选择呢?下面引用侯捷老师(STL源码剖析作者)的话:

很多人可能没有注意到,都写成第一种办法的样子,如果有人问我第一种办法可以吗?当然可以,但是效率比较差一些,不够“大气”。