继承¶
新类派生自已存在的类的机制称为继承(inheritance
)
语法¶
class Derived : [virtual] [access-specifier] Base
{
// member list
};
class Derived : [virtual] [access-specifier] Base1,
[virtual] [access-specifier] Base2, . . .
{
// member list
};
access-specifier
可分为private/protected/public
,默认是private
- virtual关键字可选,如果存在,表示基类引用为虚拟基类
virtual函数¶
虚函数是期望在派生类中重新定义的成员函数。当使用指针或对基类的引用引用派生类对象时,可以为该对象调用虚拟函数并执行派生类的函数版本
- 虚函数可以有函数体实现,也可以仅声明而已
- 如果基类非虚函数和派生类函数同名,那么调用时通过对象声明类型指向基类还是派生类决定调用的函数实现
- 对于虚函数实现,可以在调用时使用域名解析运算符显式指定基类的虚函数
。。。
。。。
int main() {
// Declare an object of type Derived.
Derived aDerived;
// Declare two pointers, one of type Derived * and the other
// of type Base *, and initialize them to point to aDerived.
Derived *pDerived = &aDerived;
Base *pBase = &aDerived;
// Call the functions.
pBase->NameOf(); // Call virtual function.
pBase->InvokingClass(); // Call nonvirtual function.
pDerived->NameOf(); // Call virtual function.
pDerived->InvokingClass(); // Call nonvirtual function.
CheckingAccount *pChecking = new CheckingAccount( 100.00 );
pChecking->Account::PrintBalance(); // Explicit qualification.
Account *pAccount = pChecking; // Call Account::PrintBalance
pAccount->Account::PrintBalance(); // Explicit qualification.
}
单继承¶
单继承模式指的是派生类仅继承自一个基类
多继承¶
多继承模式指的是派送类可以继承自多个基类。基类的排列顺序指定了构造器和析构器的调用顺序
每个派生类都包含在基类中定义的数据成员的副本。在多继承模式下,一个基类可能间接多次被继承,那么会有多个副本被使用,浪费内存空间。将基类声明为virtual
表示派生类共享同一个基类副本
与非虚拟继承相比,虚拟继承具有显著的规模优势。但是,它会带来额外的处理开销
命名歧义¶
多继承模式下,使用派生类对象调用基类函数,可能会造成命名歧义:即在不同基类中出现多个同名函数
编译器遵循如下规则:
- 如果对名称的访问不明确(如前所述),将生成错误消息
- 如果重载函数是明确的,则会解决它们
- 如果对名称的访问违反了成员访问权限,则会生成错误消息
对于出现命名歧义时,需要通过访问限定符明确使用方法
// Declare two base classes, A and B.
class A {
public:
unsigned a;
unsigned b();
};
class B {
public:
unsigned a(); // Note that class A also has a member "a"
int b(); // and a member "b".
char c;
};
// Define class C as derived from A and B.
class C : public A, public B {};
int main() {
C *pc = new C;
pc->b(); # 错误
pc->B::a(); # 正确
}
抽象类¶
抽象类充当一般概念的表达式,从中可以派生出更具体的类。不能创建抽象类类型的对象;但是可以使用指向抽象类类型的指针和引用
包含至少一个纯虚函数的类被视为抽象类。从抽象类派生的类必须实现纯虚函数,否则它们也是抽象类。
class Account {
public:
Account( double d ); // Constructor.
virtual double GetBalance(); // Obtain balance.
virtual void PrintBalance() = 0; // Pure virtual function.
private:
double _balance;
};
纯虚说明符是=0
,所以PrintBalance
是纯虚函数,类Account
是一个抽象类
抽象类无法作用于以下场景:
- 变量或成员数据
- 参数类型
- 函数返回类型
- 显式转换类型
纯虚函数可以有函数定义
class base {
public:
base() {}
// 纯虚函数
virtual ~base()=0;
};
// Provide a definition for destructor.
base::~base() {}