派生类概述
利用继续机制,新的类可以从已有的类中派生(有关继续见下一节“单一继续”的开始)。那些用于派生的类称为这些非凡派生出的类的“基类”。派生类的说明可以用下面的语法。
语法
基类说明::
基类表
基类表:
基类说明符
基类表,基类说明符
基类说明符:
完全类名称
virtual 访问说明符opt 完全类名称
访问指示符 virtualopt 完全类名称
访问指示符:
private
protected
public
单一继续
在“单一继续”这种最普通的形式中,派生类仅有一个基类,考虑如图9.1所示的关系。
注重图9.1中的从一般到非凡的过程。在类的层次设计中,可以发现一些普遍的特性,即派生类总是同基类有“kind of”关系。在图9.1中书是一种印刷好的文档而一本平装书是一种书。
在图9.1中的另一个值得注重点是Book既是派生类(从PrintedDocument中派生),也是基类(PaperbackBook是从Book派生的)。下面的例子是这种类层次的一个轮廓性的说明。
class PrintedDocument
{
//成员表
};
//Book是从PrintedDocument中派生的
class Book:public PrintedDocument
{
//成员表
};
//PaperbackBook是从Book中派生
class PaperbackBook: public Book
{
//成员表
};
PrintedDocument作为Book的直接基类,它同时也是PaperbackBook的非直接基类。直接基类和非直接基类的区别在于直接基类出现在类说明的基类表中,而非直接基类不出现在基类表中。
每个派生类的说明是在基类的说明之后说明的, 因此对于基类仅只给出一个前向引用的说明是不够的,必须是完全的说明。
在前面的例子中,使用的访问说明符是public。公有继续、私有继续以及保护的继续在第10章“成员访问控制”中讲述。
一个类可以作为很多非凡类的基类,如图9.2所示。
在图9.2中的图叫“有向无环图”(DAG)。有一些类是多个派生类的基类。但反过来不是真的:对于任意给的派生类仅有一个直接基类。图9.2描绘了单一继续的结构。
注重:有向无环图并不仅用于单一继续。它们也可以用于多重继续图。这一主题将在下一节中的“多重继续”中论述。
在继续中,派生类含有基类的成员加上任何你新增的成员。结果派生类可以引用基类的成员(除非这些成员在派生类中重定义了)。当在派生类中重定义直接基类或间接基类的成员时,可以使用范围分辨符(::)引用这些成员。考虑下面的代码:
class Document
{
public:
char * Name;//文档名称
void PrintNameOf(); //打印名称
};
//实现类Document的PrintNameOf函数
void Document::PrintNameOf()
{
cout << Name << end ;
}
class Book:public Document
{
public:
Book(char *name, long pagecount);
private:
long PageCount;
};
//class Book 构造函数
Book::Book (char *name, long pagecount)
{
Name=mew char [strlen(name)+1];
strcpy (Name,name);
PageCount=pagecount;
};
注重,Book的构造函数(Book::Book)具有对数据成员Name的访问权。在程序中可以按如下方式创建Book类对象并使用之。
//创建一个Book类的新对象,这将激活构造函数Book:BookBook
LibraryBook ("Programming Windows,2nd Ed",994);
...
//使用从Document中继续的函数PrintNameOf.
LibraryBook.PrintNameOf();如前面例子所示,类成员和继续的数据与函数以一致的方式引用。假如类Book所调用的PrintNameOf是由类Book重新定义实现的,则原来属于类Document的PrintNameOf函数只能用范围分辩符(::)才能使用:
class Book:public Docu
