继承
分类
单个继承
只指定了一个基类的叫做单继承。比如下图:
class PrintedDocument {
};
class Book : public PrintedDocument {
};
class PaperbackBook : public Book {
};
在继承中,派生类包含基类的成员以及您添加的所有新成员。 因此,派生类可以引用基类的成员(除非在派生类中重新定义这些成员):
#include <ostream>
#include <cstring>
#include <iostream>
using namespace std;
class Document{
public:
char *Name;
void PrintNameOf();
} ;
void Document::PrintNameOf(){
cout << Name << endl;
}
class Book : public Document{
public:
Book(char *name, long pagecount);
private:
long PageCount;
};
Book::Book(char *name, long pagecount){
Name = new char[strlen(name) + 1]; //===》 访问了基类Book.Name数据成员
strncpy(Name, name, strlen(name));
// strcpy_s( Name, strlen(Name), name );
PageCount = pagecount;
}
int main() {
Book LibraryBook((char *)"Programming Windows, 2nd Ed", 944 );
LibraryBook.PrintNameOf(); // ===》引用了基类Book.PrintNameOf成员函数
}
当在派生类中重新定义了直接或间接基类的成员时,范围解析运算符(::)
可用于引用这些成员。
#include <ostream>
#include <cstring>
#include <iostream>
using namespace std;
class Document{
public:
char *Name;
void PrintNameOf();
} ;
void Document::PrintNameOf(){
cout << Name << endl;
}
class Book : public Document{
public:
Book(char *name, long pagecount);
void PrintNameOf();
private:
long PageCount;
};
Book::Book(char *name, long pagecount){
Name = new char[strlen(name) + 1]; //===》 访问了基类Book.Name数据成员
strncpy(Name, name, strlen(name));
// strcpy_s( Name, strlen(Name), name );
PageCount = pagecount;
}
void Book::PrintNameOf() {
cout << "Name of book: ";
Document::PrintNameOf();
}
int main() {
Book LibraryBook((char *)"Programming Windows, 2nd Ed", 944 );
LibraryBook.PrintNameOf(); // ===》引用了自己的
}
注:强制使用基类来实现函数(如 PrintNameOf)通常不是最佳设计。虚函数 提供其他设计替代项。
如果存在可访问的明确基类,则可以隐式将派生类的指针和引用转换为其基类的指针和引用。 下面的代码使用指针演示了此概念(相同的原则适用于引用):
struct Document {
char *Name;
void PrintNameOf() {
}
};
class PaperbackBook : public Document {
};
int main() {
Document * DocLib[10]; // Library of ten documents.
for (int i = 0 ; i < 5 ; i++)
DocLib[i] = new Document;
for (int i = 5 ; i < 10 ; i++)
DocLib[i] = new PaperbackBook;
}
在前面的示例中,创建了不同的类型。 但是,由于这些类型都派生自 Document 类,因此存在对 Document * 的隐式转换。 因此,DocLib 是“异类列表”(其中包含的所有对象并非属于同一类型),该列表包含不同类型的对象。