单一继承
在 “单一继承,”继承,类的一个常见形式仅有一个基类。考虑该关系声明在下图中。
简单的单继承关系图
注意从泛型进度到在该图中的特定。在大多数类层次结构模型中的另一个常用属性是派生类具有 “与基类的关系。在该图中, Book 是一 PrintedDocument,并且, PaperbackBook 是一 book。
说明一个其他项目在运行的: Book 是派生类 (从 PrintedDocument) 和基类 (PaperbackBook 从 Book派生)。此类层次结构中的一个骨骼声明如下面的示例所示:
// deriv_SingleInheritance.cpp
// compile with: /LD
class PrintedDocument {};
// Book is derived from PrintedDocument.
class Book : public PrintedDocument {};
// PaperbackBook is derived from Book.
class PaperbackBook : public Book {};
PrintedDocument 被视为到 Book“直接基”类;它是 “间接基”类将 PaperbackBook。不同之处是直接基类出现在基础列表类声明,并且一个间接基不。
每类派生的基类在派生类中的声明之前声明。为基类提供了一个前向引用的声明不足够;它必须是一个完整的声明。
在前面的示例中,使用访问说明符 公共 。公共的含义,保护和私有继承在 成员访问控件。所述
类可用作基类用作多个特定的类,如下图所示。
处理的非循环性关系图示例
在显示的关系图中,名为 “处理非循环性关系图” (或 “DAG”),某些类是多个派生类的基类。但是,如果反转不为真:只有任何特定派生类的一个直接基类。在该图中的关系图显示一个 “继承”结构。
说明 |
---|
处理的非循环性关系图不是唯一的单个继承。它们还用于表示多重继承关系图。本主题介绍 多重继承中。 |
在继承,派生类包含基类的成员以及您添加的所有新成员。因此, (除非这些成员在派生类中重新定义),派生类可以引用基类的成员。范围解析运算符 (::) 可以使用引用直接或间接基类的成员,则这些成员在派生类中重新定义。请看以下示例:
// deriv_SingleInheritance2.cpp
// compile with: /EHsc /c
#include <iostream>
using namespace std;
class Document {
public:
char *Name; // Document name.
void PrintNameOf(); // Print name.
};
// Implementation of PrintNameOf function from class Document.
void Document::PrintNameOf() {
cout << Name << endl;
}
class Book : public Document {
public:
Book( char *name, long pagecount );
private:
long PageCount;
};
// Constructor from class Book.
Book::Book( char *name, long pagecount ) {
Name = new char[ strlen( name ) + 1 ];
strcpy_s( Name, strlen(Name), name );
PageCount = pagecount;
};
请注意 Book的构造函数,Book::Book(),访问数据成员, Name。在过程中,可以创建和使用类型 Book 对象如下所示:
// Create a new object of type Book. This invokes the
// constructor Book::Book.
Book LibraryBook( "Programming Windows, 2nd Ed", 944 );
...
// Use PrintNameOf function inherited from class Document.
LibraryBook.PrintNameOf();
在前面的示例所示,同样使用类成员和继承的数据和功能。如果类的 Book 实现要求 PrintNameOf 功能的 reimplementation,属于 Document 类使用范围解析 (::) 运算符的功能,只能调用:
// deriv_SingleInheritance3.cpp
// compile with: /EHsc /LD
#include <iostream>
using namespace std;
class Document {
public:
char *Name; // Document name.
void PrintNameOf() {} // Print name.
};
class Book : public Document {
Book( char *name, long pagecount );
void PrintNameOf();
long PageCount;
};
void Book::PrintNameOf() {
cout << "Name of book: ";
Document::PrintNameOf();
}
,如果有可访问,明确的基类,指针和对派生类可以隐式转换为指针并对它们的基类。下面的代码演示了此概念使用指针 (相同的原则适用于引用):
// deriv_SingleInheritance4.cpp
// compile with: /W3
struct Document {
char *Name;
void PrintNameOf() {}
};
class PaperbackBook : public Document {};
int main() {
Document * DocLib[10]; // Library of ten documents.
for (int i = 0 ; i < 10 ; i++)
DocLib[i] = new Document;
}
在前面的示例中,不同的类型创建的。但是,在中,因为这些类型均从 Document 类派生,对 Document *的隐式转换。因此, DocLib 为 “异类的列表” (不是所有的对象都属于同一类型) 的列表包含不同类型的对象。
由于 Document 类具有一个 PrintNameOf 功能,它可以在库中打印每本书的名称,不过,它可以忽略某些特定信息到文档类型 ( Book的页计数,字节数 HelpFile的,等等)。
说明 |
---|
强制基类实现一个功能 (如 PrintNameOf 通常并不是最佳方式。虚函数 提供其他模型选择。 |