Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1197773
  • 博文数量: 695
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4027
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-20 21:22
文章分类

全部博文(695)

文章存档

2018年(18)

2017年(74)

2016年(170)

2015年(102)

2014年(276)

2013年(55)

分类: C/C++

2014-01-23 23:04:23

与任何其他函数一样,构造函数具有名字、形参表和函数体。
与其他函数不同的是,构造函数也可以包含一个构造函数初始化列表:
构造函数初始化列表以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个数据成员后面跟一个放在圆括号中的初始化式。如下例:
//recommedned way to write constructors using a constructor initializer
Sales_item::Sales_item(const string &book):
        isbn(book),units_sold(0),revenue(0.0)
{}
这个构造函数将成员isbn初始化为形参book的值,将units_sold和revenue初始化为0。与任意的成员函数一样,构造函数可以定义在类的内部或外部。构造函数初始化式只在构造函数的定义中而不是声明中指定。
注:构造函数初始化列表是许多相当有经验的C++程序员都没有掌握的一个特性。

构造函数初始化列表难以理解的一个原因在于,省略初始化列表并在构造函数的函数体内对数据成员赋值是合法的。
例如,可以将接受一个string的Sales_item构造函数编写为:
//legal but sloppier way to write the constructor: no constructor initializer
Sales_item::Sales_item(const string &book)
{
      isbn = book;
      units_sold = 0;
      revenue = 0.0;
}
这个构造函数给类Sales_item的成员赋值,但没有进行显式初始化。
不管是否有显式的初始化式,在执行构造函数之前,要初始化isbn成员。这个构造函数隐式使用默认的string构造函数来初始化isbn。执行构造函数的函数体时,isbn成员已经有值了。该值被构造函数函数体中的赋值所覆盖。
从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2)普通计算阶段。
计算阶段由构造函数函数体中的所有语句组成。
注:不管成员是否在构造函数初始始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。初始化发生在计算阶段开始之前。
以上的两个Sales_item 构造函数版本具有相同的效果。构造函数体执行结束后,三个数据成员保存同样的值。不同之处在于,使用构造函数初始化列表的版本是对数据成员初始化,而没有定义初始化列表的构造函数版本在构造函数函数体中对数据成员赋值。这个区别的重要性取决于数据成员的类型。
有些成员必须在构造函数初始化列表中进行初始化。对于这样的成员,在构造函数函数体中对它们赋值不起作用。这样的成员包括:没有默认构造函数的类类型的成员、const或引用类型的成员。
因为内置类型的成员不进行隐式初始化,所以对这些成员是进行初始化还是赋值似乎都无关紧要。
注意以下两个例子:
class ConstRef
{
    public:
        ConstRef(int ii);
    private:
        int i;
        const int ci;
        int &ri;
};
// no explicit constructor initializer: error ri is uninitialized
ConstRef::ConstRef(int ii)
{                         //assignments:
      i = ii; //ok
      ci = ii;//error: cannot assign to a const
      ri = i; //assigns to ri which was not bound to an object
}
记住,可以初始化const对象或引用类型的对象,但不能对它们赋值。在开始执行构造函数的函数体之前,要完成初始化。初始化const或引用类型数据成员的唯一机会是在构造函数初始化列表中。
编写该构造函数的正确方式为
//ok: explicitly initialize reference and const members
ConstRef::ConstRef(int ii): i(ii), ci(i), ri(ii){}
建议:使用构造函数初始化列表
阅读(607) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~