1 继承
类的继承可以在原有类的基础上再派生一个类。原有的类叫做基类(父类)。派生出来的类叫做派生类(子类)。类的继承机制使得C++可以实现很大限度的代码复用。定义派生类的基本形式为
class 派生类名:访问权限 基类名
访问权限有三种,分别是public,private和protected,通常定义派生类的访问权限为public。派生类可以自动获得基类中的全部数据成员和成员函数,而且除了private类型,其他类型在在派生类中可以直接访问。派生类也可以定义自己的数据成员和成员函数。
派生类的对象在生成时,也需要利用构造函数进行初始化。在初始化时,会先调用基类的构造函数,对派生类中基类的数据成员进行初始化。然后再调用派生类自己的构造函数,对派生类的数据成员进行初始化。在销毁对象时,析构函数也是分别调用的。析构函数的调用顺序与构造函数相反。
对于不同的基类成员,访问权限是不同的
成员类型 | 访问权限 |
---|---|
public | 在类外和派生类中都可以访问 |
private | 只能在类内访问,不能在类外和派生类中访问 |
protected | 类内和派生类都可以访问,类外不可以访问 |
如果再定义一个成员时,没有指定访问说明符,默认为private。通过一个例子来了解一下继承
#include<iostream>
using namespace std;
// 基类
class temp
{
public:
string name;
int age;
};
class temp1 : public temp
{
public:
string number;
};
int main()
{
temp1 a; // 定义一个类tenp1的对象
// 给对象a的成员赋值
a.name = "ertu";
a.age = 23;
a.number = "20230714";
// 输出对象a成员
cout << "姓名:" << a.name << endl;
cout << "年龄:" << a.age << endl;
cout << "编号:" << a.number << endl;
return 0;
}
输出结果为
姓名:ertu
年龄:23
编号:20230714
在派生类中可以定义一个与基类成员函数同名的函数,返回类型,参数个数和参数类型都可以相同。对于在基类中已经有定义的函数,如果在派生类中再定义一个同名的函数,这称为重构或者覆盖。对于在基类中仅有声明的函数,如果在派生类中定义一个同名的函数,这成为实现。
#include<iostream>
using namespace std;
// 基类
class temp
{
public:
void function1 ()
{
cout << "调用基类函数1" << endl;
}
void function2 (); // 仅有一个声明
};
class temp1 : public temp
{
public:
// 重置基类成员函数1
void function1 ()
{
cout << "调用派生类成员函数1" << endl;
}
// 实现基类成员函数2
void function2 ()
{
cout << "调用派生类成员函数2" << endl;
}
};
int main()
{
temp a; // 定义一个temp类的对象
temp1 b; // 定义一个类tenp1的对象
// 调用成员函数
a.function1();
// a.function2(); // 基类中没有function的实现,不能调用
b.function1();
b.function2();
return 0;
}
输出结果为
调用基类函数1
调用派生类成员函数1
调用派生类成员函数2
2 多态
多态简单来说就是,一个接口,多种方法。多态也成为动态绑定或者迟后绑定。除了动态绑定还有静态绑定,下面介绍以下这两个概念
- 动态绑定
在程序运行时才知道到底调用哪个函数。如果基类指针指向基类对象,就调用基类的成员函数。如果基类指针指向派生类对象,就调用派生类的成员函数。这就要用到另外一种方法,称为动态绑定或迟后绑定。 - 静态绑定
函数调用在程序运行之前就已经和函数体(函数首地址)绑定起来。在对函数调用的源程序段进行编译时,编译器知道这个函数名的首地址在哪里,然后将这个首地址替换为函数名,一并翻译成机器码。这种编译方法称为早期绑定或静态绑定。
在C++中,动态绑定是通过虚函数实现的。定义虚函数的方法比较简单,只需要在成员函数原型前增加一个virtual关键字即可。如果一个基类成员的函数定义为虚函数,那么即使在派生类中省略了virtual关键字,该成员函数依旧为虚函数。要达到动态绑定的效果,基类和派生类的对应函数不仅名字相同,而且返回类型、参数个数和类型也必须相同。
对于虚函数有以下限制
- 只有类的成员函数才可以是虚函数
- 静态成员函数不能是虚函数
- 构造函数不能是虚函数
- 析构函数可以是虚函数,而且常常将析构函数定义为虚函数。
除了虚函数,还有一个纯虚函数的概念。纯虚函数是指只定义了函数,但是没有函数实现的虚函数。定义纯虚函数的方法是在虚函数参数表右边的括号后加一个“=0”,比如
virtual void temp (void) = 0;
含有纯虚函数的类称为抽象类。C++不允许用抽象类创造对象,它只能被其他类继承。要定义抽象类,就必须定义纯虚函数,它实际上起到一个接口的作用。