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. 动态绑定又称为后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态
相关推荐
瑞雪兆丰年兮15 小时前
[从0开始学Java|第十三天]面向对象进阶(static&继承)
java·开发语言
小楼v15 小时前
如何实现AI生成应用部署功能
java·后端·ai·部署
望未来无悔15 小时前
系统学习算法 专题十九 优先级队列(堆)
java·算法
小虾米 ~15 小时前
JAVA引用类型
java·开发语言
星辰_mya15 小时前
Elasticsearch之中
java·服务器·数据库
永远睡不够的入15 小时前
类和对象(下):流重载、初始化列表、友元
c++
fengxin_rou16 小时前
[Redis从零到精通|第三篇]:缓存更新指南
java·数据库·redis·spring·缓存
九转成圣16 小时前
告别肉眼解析!Java 递归实现 JSON 全路径自动化探测工具
java·自动化·json
_运维那些事儿16 小时前
skywalking链路追踪
java·运维·ci/cd·软件构建·skywalking·devops
范纹杉想快点毕业16 小时前
状态机设计模式与嵌入式系统开发完整指南
java·开发语言·网络·数据库·mongodb·设计模式·架构