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. 动态绑定又称为后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态
相关推荐
波音彬要多做7 分钟前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
捕鲸叉8 分钟前
C++软件设计模式之外观(Facade)模式
c++·设计模式·外观模式
wm104340 分钟前
java web springboot
java·spring boot·后端
smile-yan41 分钟前
Provides transitive vulnerable dependency maven 提示依赖存在漏洞问题的解决方法
java·maven
老马啸西风42 分钟前
NLP 中文拼写检测纠正论文-01-介绍了SIGHAN 2015 包括任务描述,数据准备, 绩效指标和评估结果
java
Earnest~1 小时前
Maven极简安装&配置-241223
java·maven
皮蛋很白1 小时前
Maven 环境变量 MAVEN_HOME 和 M2_HOME 区别以及 IDEA 修改 Maven repository 路径全局
java·maven·intellij-idea
青年有志1 小时前
JavaWeb(一) | 基本概念(web服务器、Tomcat、HTTP、Maven)、Servlet 简介
java·web
上海研博数据1 小时前
flink+kafka实现流数据处理学习
java
KpLn_HJL1 小时前
leetcode - 2139. Minimum Moves to Reach Target Score
java·数据结构·leetcode