面向对象编程系列四:继承体系中的构造函数

基类的构造函数不可以被继承,可以为public, protected, private,如果某个构造函数只希望能被派生类访问,那么可以设置为protected。

(1)派生类构造函数先调用基类的构造函数

在创建一个派生类对象时,需要调用派生类的构造函数,由于派生类对象都包含了一个或多个基类子对象,因此会在构造函数中首先调用基类的构造函数来创建基类子对象。如:

1 class Bulk_Item : public Item_Base
2 {
3   public:
4     Bulk_Item():min_qty(0),discount(0.0) { }
5 };

当要创建一个Bulk_Item对象时,首先调用基类Item_Base的默认构造函数初始化派生类对象中的Item_Base部分,然后初始化Bulk_Item的部分成员min_qty和discount,并执行构造函数的函数体。

(2)向基类构造函数传递实参

派生类构造函数的初始化列表只能初始化派生类的成员而不能初始化继承的基类成员,但可以通过在初始化列表中包含基类的构造函数来初始化基类的成员:

1 class Bulk_Item : public Item_Base
2 {
3   public:
4     Bulk_Item(const string& book = "", double sales_price = 0.0, size_t qty = 0, double disc_rate = 0.0)
      :Item_Base(book, sales_price),
       min_qty(qty),discount(disc_rate) { }
5 };

事实上,在派生类构造函数中通过调用基类构造函数来初始化基类部分体现了对基类接口的尊重,即使基类的成员是public或protected,也应尽量使用基类的构造函数来初始化基类的成员而非直接在派生类构造函数中对基类成员初始化或赋值。

(3)只能初始化直接基类

一个类只能初始化自己的直接基类,如类C继承自类B,类B继承自类A,那么C只可以直接初始化B,B的构造函数会初始化类A,这是因为定义B类的用户已经定义了如何构造和初始化B的对象,C的定义者不应在B类能够并会创建A对象的同时再次创建A对象。

(4)构造函数不应设为虚函数

构造函数在对象完全构造之前运行,此时动态类型还未完全创建成功,编译器不会根据动态类型在运行时确定构造函数,事实上,构造函数是不被继承的,不应设为virtual。

posted on 2013-06-29 20:48  Sophia-呵呵小猪  阅读(288)  评论(0编辑  收藏  举报