成员初始化列表

时间:2022-09-09 15:03:38

转载自:http://www.zdnet.com.cn/developer/code/story/0,3800066897,39154968,00.htm
作者: ZDNet China
2003-07-30 03:41 PM

成员初始化列表class ratio  {
成员初始化列表public:
成员初始化列表 ratio(int top, intbot) : //mem-init list
成员初始化列表
  x(top), y(bot)
成员初始化列表{
成员初始化列表 //ctor body. At this point
成员初始化列表 
//x & y have been initialized
成员初始化列表
}

成员初始化列表private:
成员初始化列表 int x, y;
成员初始化列表}
;

在下面几种情况下必须遵守成员初始化列表: 

初始化一个常数;
初始化引用成员;
调用base class构造函数;
调用embedded objec构造函数;
另外,成员初始化列表是任意的,但是,它在构造函数中的初始化效率更高。下面的例子充分证明了这一点。它使用了初始化数据成员的两种形式

成员初始化列表class person
成员初始化列表{
成员初始化列表string _name;
成员初始化列表public:
成员初始化列表 person(string name) {_name=name;}
成员初始化列表}
;
成员初始化列表
成员初始化列表class person
成员初始化列表{
成员初始化列表string _name;
成员初始化列表public:
成员初始化列表 person(string name) : _name(name) {}
成员初始化列表}
;

从表面上看这两个例子差不多,但深究其实质却大不一样。第一个例子中,自变量被传值,当它在执行时,一个副本在构造函数的栈中被创建,当构造函数终止运行时,这个副本就被杀死。

对比来看第二个例子,它避免创建副本并杀死它的过程,因为使用了成员初始化列表。通常,当初始化的成员为类时,成员初始化列表比构造函数列表更有效。 
第二个例子仍然没有避免副本的创建,因为是否创建副本取决于函数的参数是string对象的值类型还是引用类型,这里使用了值传递,必然会创建副本,这两个例子的区别在于,前者会先调用成员_name的无参数构造函数,在进行赋值,而后者是直接调用拷贝构造函数对_name进行构造。(编辑:2011-06-24)

一个非行内的构造函数的成员初始化列表通常出现在定义中而不是声明中。在下面的例子中,class body包含了一个声明的构造函数,这个构造函数没有成员初始化列表,成员初始化列表出现在构造函数的定义中
 

成员初始化列表class ratio  {
成员初始化列表public:
成员初始化列表 ratio(int top, intbot); // no initialization list here
成员初始化列表
}
;
成员初始化列表
成员初始化列表ratio::ratio( int top, intbot) : x(top), y(bot)
成员初始化列表{}