本身不是派生类的基类,其构造函数和复制控制基本上不受继承的影响。构造
函数看起来像已经见过的许多构造函数一样:
Item_base( const std::string &book = "", double sales_price = 0.0):isbn(book),price( sales_price){}
继承对基类构造函数的唯一影响是,在确定踢狗写构造函数时,必须考虑一类新用户。
想任意其他成员一样,凑早函数可以为proteced或private;
某些类需要只希望派生类使用的特殊函数,这样的构造函数应定义为proteced
15.4.2 派生类的构造函数
派生类的构造函数受继承关系的影响,每个拍沈磊构造函数除了初始化自己的数据成员之外,还有初始化基类。
合成的派生类默认构造函数
派生类的合成默认构造函数除了初始化派生类的数据成员之外,还初始化派生类对象的基类部分,基类、
部分有基类的默认构造函数初始化。
对于Bulk——item类,合成的默认构造函数会这样执行
1. 调用Item_base的默认构造函数,将isbn成员初始化空串,将price成员初始化为0
2.用常规变量初始化规则初始化Bulk_item的成员,也就是说,qty和discount 成员会是未初始化的。
定义默认构造函数
因为Bulk_item具有内置类型成员,所以应该定义自己的默认构造函数
class Bulk_item : public Item_base
{
public :
Bulk_item() : min_aty(0),discount( 0.0){}
};
这个构造函数使用构造函数初始化列表初始化,该构造函数还隐式调用Item_base的默认构造函数初始化对象的基类部分。
运行这个构造函数的效果是,首先使用Item_base的默认构造函数初始化Item_base部分,那个构造函数将isbn置为空串讲price置为0,Item_base的构造函数执行完毕后,在初始化Bulk_item部分的成员并执行构造函数的函数体
向基类构造函数传递实参
除了默认的构造函数之外,Item_base类还使用用户能够初始化的isbn和price成员,我们希望支持同样Bulk_item对象
的初始化,事实上,我们希望用户能够制定整个BUlk_item的值,包括折扣率和数量
派生类的构造函数的初始化列表只能初始化派生类的成员,不能直接初始化继承的成员。相反派生类的构造函数通过将基类
包含在构造函数初始化列表中来简直初始化继承的成员。
class Bulk_item : public Item_base {
public :
Bulk_item ( const std::string &book, double sales_price, std::size_t qty = 0, double disc_rate = 0.0 ):
Item_base( book, sales_price ), min_qty( qty ) , discount ( disc_rate ){}
};
这个构造函数使用两个形参Item_base 构造函数吃石化基类子对象,他讲自己的book和 sales_price实参传递给
该构造函数。这个构造函数可以这样使用:
Bulk_item bulk( "0-22-565-+454---555" , 50, 5, 49 ) ;
要简历bulk,首先运行基类的构造函数,该构造函数使用从子类构造函数初始化列表传来的实参初始化isbn和price,基类的构造函数执行完毕后,在初始化子类成员,最后运行bulk_item构造函数的函数体
构造函数初始化列表为类的基类和成员提供的初始值,它并不是指定初始化的执行次序,首先初始化基类,然后根据声名
次序初始化派生类的成员。
在派生类构造函数中使用默认实参
当然,也可以将两个Bulk_item构造函数写为一个接受默认实参的构造函数
只能初始化直接基类
一个类只能初始化自己的直接基类。直接就是拍派生列表中指定的类。如果类c从类b派生,类b从类a派生,则
b是c的直接基类。虽然每个c类对象包含一个a类部分,但c的构造函数不能直接初始化a部分。相反,需要类c初始化b,
b的构造函数在初始化a。这一限制的原因是,类b的作者已经制定了怎样构造和初始化b对象,像类b
的任何用户一样,
关键概念:重构
将disc_item加到Item_base层次是重构的一个例子。重构包括重新定义类层次,将操作数据从一个类
迁移到另一个类,为了适应应用程序的需要而重新设计类以便增加新函数或者处理其他改变时,最后可能重构
重构常见在面向对象应用程序中非常常见。值得注意的是,虽然改变了继承层次,使用Bulk_item类作者Item_base类的
代码不需要改变,然而,对类进行重构,或者以任意方式改变类,使用这些类的任意代码都必须重新编译。
关键概念:尊重基类接口
构造函数只能初始化其直接基类的原因是每个类都定义了自己的接口,定义disc_tem时,
通过定义它的构造函数制定了怎样初始化对象,一旦定义了自己的接口,与该类对象的所有交互都应该通过
该接口,即使