C++——多态

1. 多态的概念

多态是面向对象编程中的一种特性,它允许使用相同的接口来表示不同的实现。(去完成某个行为时,当不同的对象去完成时会产生不同的状态)

2. 多态的定义

在C++中,多态性的实现主要依赖于继承和虚函数。基类中的虚函数可以在派生类中被重写,从而实现了运行时的多态性。这种机制被称为动态绑定。同一接口可以有不同的实现方式,多态允许基类的指针指向子类的方法。

3. 多态的实现

3.1 在继承中构成多态的条件:

  1. 必须通过基类的指针或者引用调用虚函数

  2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

3.2 虚函数

虚函数:即被virtual的类成员函数称为虚函数

cpp 复制代码
class Person
{
public:
	virtual void BuyTicket()
	{
		cout << "买票全价" << endl;
	}
};

3.3 虚函数的重写

虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型函数名字参数列表完全相同),称子类的虚函数重写了基类的虚函数

特殊情况:

  1. 协变(基类与派生类虚函数返回值类型不同)

派生类重写基类虚函数时,与基类虚函数返回值类型不同,即基类虚函数返回基类对象的指针或者引用。派生类虚函数返回派生类对象的指针或者引用时,称为协变。

cpp 复制代码
class A{};
class B:public A{};
class Person
{
public:
	virtual A* f() { return new A; }
};
class Student :public Person
{
public:
	virtual B* f() { return new B; }
};
  1. 析构函数的重写(基类与派生类析构函数的名字不同)

如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加 virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。虽然函数名不相同,看起来违背了重写的规则。其实这里可以理解为编译器对析构函数做了特殊处理,编译器后析构函数的名称统一处理成destructor

cpp 复制代码
class Person
{
public:
	virtual ~Person() { cout << "~Person()" << endl; }
};
class Student :public Person
{
	virtual ~Student() { cout << "~Student" << endl; }
};
int main()
{
	Person* p1 = new Person;
	Person* p2 = new Student;
	delete p1;
	delete p2;
}
//~Person()
//~Student
//~Person()

3.4 C++11关键字

  1. final:修饰虚函数,表示该虚函数不能再被重写
  1. voerride :检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错
cpp 复制代码
class Car
{
public: 
	virtual void Drive(){}
};
class Benz :public Car
{
public:
	virtual void Drive() override { cout << "Benz-舒适" << endl; }
};

3.5 重载/重写/重定义的对比

4. 抽象类

4.1 概念

在虚函数的后面加上=0,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象,纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。

4.2 接口继承和实现继承

普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达到多态,继承的是接口。所以如果不实现多态,不要把函数定义成虚函数

5. 动态绑定与静态绑定

  1. 静态绑定又称为前期绑定(早绑定),在程序编译期间确定了程序的行为,也称为静态多态
  2. 动态绑定又称为后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态
相关推荐
鱼跃鹰飞2 小时前
设计模式系列:工厂模式
java·设计模式·系统架构
a努力。2 小时前
国家电网Java面试被问:混沌工程在分布式系统中的应用
java·开发语言·数据库·git·mysql·面试·职场和发展
Yvonne爱编码2 小时前
Java 四大内部类全解析:从设计本质到实战应用
java·开发语言·python
J2虾虾2 小时前
SpringBoot和mybatis Plus不兼容报错的问题
java·spring boot·mybatis
毕设源码-郭学长3 小时前
【开题答辩全过程】以 基于springboot 的豪华婚车租赁系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
imX2G3 小时前
爆破小游戏2.0
c++
Cx330❀4 小时前
【优选算法必刷100题】第41-42题(模拟):Z 字形变换,外观数列
c++·算法
Cx330❀4 小时前
【优选算法必刷100题】第038题(位运算):消失的两个数字
开发语言·c++·算法·leetcode·面试
燃于AC之乐4 小时前
我的算法修炼之路--5——专破“思维陷阱”,那些让你拍案叫绝的非常规秒解
c++·算法·贪心算法·bfs·二分答案·扩展域并查集·动态规划(最长上升子序列)
艾莉丝努力练剑4 小时前
【优选算法必刷100题】第021~22题(二分查找算法):山脉数组的峰顶索引、寻找峰值
数据结构·c++·算法·leetcode·stl