继承时面向对象的主要特征(还有封装和多态)之一。它使得一个类可以从现有的类中派生,从而不必再重新定义一个类。
旧类被称为基类或父类,新类被称为派生类或子类。
类的继承形式:
class 派生类名标识符 :继承方式 基类名标识符
{
访问控制修饰符:
[成员声明列表]
}
继承方式有public、private、protected 3种。
- public(共有型派生)基类中的public数据成员和成员函数,在派生类中仍然是public
- private(私有型派生)基类中的public、protected数据成员和成员函数,再派生类中可以访问。基类的private数据成员,在派生类中不可以访问
- protected(保护型派生)基类中的public、protected数据成员和成员函数,在派生类中均为protected。protected类型在派生类定义时可以访问,用派生类声明对象时不可以访问。即:类体外不可以访问
构造函数访问顺序:
在定义派生类对象时,首先调用的是父类的构造函数,然后是派生类的构造函数。子类对象的释放过程则与其构造过程相反。
子类隐藏父类的成员函数:
如果在派生类中有与父类同名的成员函数,则调用时只有子类的成员函数,父类的成员函数被隐藏(只要同名,就会被隐藏)。如果想访问父类的被隐藏的成员函数,需要显式使用父类名,例如:
#include<iostream>
using namespace std;
class CEmployee
{
void output()
{
cout<<"1";
}
}
class COperatoer:public CEmployee
{
void output()
{
cout<<"2";
}
}
int main()
{
COperatoer optr;
optr.CEmployee::output();
return 0;
}
C++允许子类从多个父类继承共有和受保护的成员,这被称为多重继承。
声明形式如下:
class 派生类名标识符: 继承方式1 基类名标识符1,继承方式2 基类名标识符2
{
访问控制标识符:
成员声明列表
}
如果父类1与父类2中有同名函数,那么在派生类中直接调用将会出现编译错误。
需要指定类名:
waterbird.CFish::Breath();//派生类waterbird调用父类CFish的Breath函数
waterbird.CBird::Breath();//派生类waterbird调用父类CBird的Breath函数
多重继承的构造顺序:
父类1,父类2,......,子类
在C++中,存在两种类型多态性,即函数重载和虚函数。
虚函数允许在派生类中重新定义与基类函数同名的函数,并且可以通过基类指针或引用来访问基类或派生类中的同名函数。
多态主要体现在虚函数上,只要虚函数存在,对象类型就会在程序运行时动态绑定。动态绑定的实现方法是定义一个指向基类对象的指针并使它指向同一类族中需要调用该函数的对象,通过该指针变量调用此虚函数。
包含有纯虚函数的类称为抽象类,一个抽象类至少含有一个纯虚函数。抽象类只能作为基类派生出新的子类,而不能在过程中被实例化。
纯虚函数是指被标明为不具体实现的虚成员函数。
当基类是抽象类时,在派生类中必须给出基类中纯虚函数的定义,活在该类中再次声明其为纯虚函数。
抽象类的主要作用是将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作。所以派生类实际上刻画了一组子类的操作接口的通用语义,这些语义也传给子类,子类可以具体实现这些语义,也可以再将这些语义传给自己的子类。