C++的类与继承(二)

01

多继承


多继承即一个子类可以有多个父类,它继承了多个父类的特性。

C++ 类可以从多个类继承成员,语法如下:

class:1>1>,2>2>,…{};


当上面的代码被编译和执行时,它会产生下列结果:

Total area:35Total paint cost: $245002构造函数

类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。

构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void,可以有0-n个形参。构造函数可用于为某些成员变量设置初始值。

构造函数具有以下特点:

*构造函数可以重载:只要每个构造函数形参表唯一,同一个类中的构造函数数量不限:

*构造函数自动执行;

*构造函数可以包含一个构造函数初始化列表

* 没有默认构造函数的类类型的成员,以及 const 或引用类型的成员,必须在初始化列表中完成初始化。

初始化表达式:

Sales_item(const std::string &book, int cnt, double price): isbn(book), units_sold(cnt), revenue(cnt * price) { }

范例:


class ConstRef

{

public:

ConstRef(int ii);

private:

int i;

const int ci;

int &ri;

};

ConstRef::ConstRef(int ii)

{

i = ii; // ok

ci = ii; // error

ri = i; //

}

应该这么初始化:

ConstRef::ConstRef(int ii): i(ii), ci(i), ri(ii) { }


*不含形参的构造函数就是默认构造函数。

注意:

只有当一个类没有定义构造函数时,编译器才会自动生成一个默认构造函数。

一个类只要定义了一个构造函数,编译器也不会再生成默认构造函数。

03

析构函数



析构函数是构造函数的互补:当对象超出作用域或动态分配的对象被删除时,将自动应用析构函数。

析构函数可用于释放构造对象时或在对象的生命期中所获取的资源。

析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

当上面的代码被编译和执行时,它会产生下列结果:

Objectis being createdLength of line :6Objectis being deleted

构造函数的用途之一是自动获取资源;与之相对的是,析构函数的用途之一是回收资源。除此之外,析构函数可以执行任意类设计者希望在该类对象的使用完毕之后执行的操作。


(1) 何时调用析构函数

撤销(销毁)类对象时会自动调用析构函数。

变量(类对象)在超出作用域时应该自动撤销(销毁)。

动态分配的对象(new A)只有在指向该对象的指针被删除时才撤销(销毁)。

撤销(销毁)一个容器(不管是标准库容器还是内置数组)时,也会运行容器中的类类型元素的析构函数(容器中的元素总是从后往前撤销)。

(2)何时编写显式析构函数
如果类需要定义析构函数,则它也需要定义赋值操作符和复制构造函数,这个规则常称为三法则:如果类需要析构函数,则需要所有这三个复制控制成员。
(3)合成析构函数

合成析构函数按对象创建时的逆序撤销每个非 static 成员,因此,它按成员在类中声明次序的逆序撤销成员。

对于每个类类型的成员,合成析构函数调用该成员的析构函数来撤销对象。

合成析构函数并不删除指针成员所指向的对象。 所以,如果有指针成员,一定要定义自己的析构函数来删除指针。

析构函数与复制构造函数或赋值操作符之间的一个重要区别:即使我们编写了自己的析构函数,合成析构函数仍然运行。