当前位置: 首页 > article >正文

【C++】多态语法概念

目录

    • 一、概念及定义
    • 二、虚函数重写的特例
    • 三、final和override
    • 四、抽象类

一、概念及定义

概念:在继承关系下的不同类,调用同一个函数,产生不同的行为,叫作多态。

图示:
在这里插入图片描述

定义:必须通过基类的指针或者引用调用虚函数;被调用的函数必须是虚函数。类里的函数的返回类型前加上virtual就是虚函数,子类继承父类的虚函数叫作重写,重写的是虚函数的实现,该虚函数的返回类型、函数名、参数列表都要与父类相同(有两个特例,后面再谈)。

class Person
{
public:
	virtual void func()
	{
		cout << "全价" << endl;
	}
};

class Student :public Person
{
public:
	virtual void func()
	{
		cout << "半价" << endl;
	}
};

void test1(Person* ps)//通过基类的指针
{
	ps->func();//调用虚函数
}

void test2(Person& ps)//通过基类的引用
{
	ps.func();//调用虚函数
}

int main()
{
	Person p;
	Student s;
	test1(&p);
	test1(&s);
	test2(p);
	test2(s);
	return 0;
}

在这里插入图片描述

注:子类的虚函数加不加virtual都没关系,但是父类一定要有virtual,否则就不是虚函数了。一般为了规范,子类也最好加上virtual

二、虚函数重写的特例

1️⃣协变
父子类的虚函数返回类型可以不相同。基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用。

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; 
	}
};

2️⃣析构函数的重写
如果基类的析构函数是虚函数,只要派生类的析构函数定义了,不管加不加virtual,都是虚函数。两个析构函数的函数名不相同也构成重写,因为编译器有作特殊处理,编译后析构函数的名称统一处理成destructor。

class Person
{
public:
	virtual ~Person()
	{
		cout << "~Person()" << endl;
	}
};

class Student :public Person
{
public:
	virtual ~Student()
	{
		cout << "~Student()" << endl;
	}
};

int main()
{
	Person* p = new Person;
	Person* s = new Student;
	delete p;
	delete s;
	return 0;
}

在这里插入图片描述

三、final和override

1️⃣final关键字修饰虚函数,该虚函数不能被重写
在这里插入图片描述

2️⃣override关键字是用来检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。
在这里插入图片描述

四、抽象类

概念:包含纯虚函数的类叫抽象类。纯虚函数:在虚函数的后面写上 =0,就称为纯虚函数。抽象类不能实例化对象,继承它的派生类只有重写纯虚函数才能实例化出对象。

class Animal
{
public:
	virtual void Action() = 0;//抽象类,纯虚函数声明即可
};

class Dog :public Animal
{
public:
	virtual void Action()//对纯虚函数进行重写
	{
		cout << "running!" << endl;
	}
};

class Bird :public Animal
{
public:
	virtual void Action()//对纯虚函数进行重写
	{
		cout << "flying!" << endl;
	}
};

int main()
{
	Animal* d = new Dog;
	Animal* b = new Bird;
	d->Action();
	b->Action();
	return 0;
}

在这里插入图片描述


http://www.kler.cn/a/234554.html

相关文章:

  • Oracle ADB 导入 BANK_GRAPH 的学习数据
  • Llama微调测试记录
  • 【HarmonyOS NEXT】一次开发多端部署(以轮播图、Tab栏、列表为例,配合栅格布局与媒体查询,进行 UI 的一多开发)
  • C++中的栈(Stack)和堆(Heap)
  • 搭建Python2和Python3虚拟环境
  • NAT网络工作原理和NAT类型
  • springboot174基于springboot的疾病防控综合系统的设计与实现
  • Springboot 2.5.x如何集成Nacos 2.x的配置管理功能?
  • C语言之预处理详解
  • svg基础(八)滤镜-feTurbulence(湍流)
  • Elasticsearch:混合搜索是 GenAI 应用的未来
  • 服务器解析漏洞及任意文件下载
  • 【实验1】分布式模式的CentOS 6上安装Hadoop(1个master节点,2个slave节点)
  • ChatGPT 4:新特性与优势
  • postgresql 手动清理wal日志的101个坑
  • AI:125-基于深度学习的航拍图像中地物变化检测
  • 8 scala的共生对象
  • 小游戏和GUI编程(5) | SVG图像格式简介
  • 如何实现Vuex本地存储
  • 单片机学习笔记---AT24C02(I2C总线)
  • FATFS学习笔记——FATFS写文件的两种方式
  • 在Ubuntu22.04上部署ComfyUI
  • Java 学习和实践笔记(6)
  • MYSQL分区NOW()不支持
  • MySQL 表的增删查改(练习)
  • 【Spring源码分析】Spring的启动流程源码解析