c++多态

2023-09-17 10:26:39

目录

多态的概念

多态实现计算器案例

c++如何实现动态绑定

纯虚函数和抽象类

纯虚函数和多继承

虚析构函数

虚析构函数作用

纯虚析构函数

重载 重定义 重写


多态的概念

多态:一种接口,多种形态

静态多态:如果函数的调用,在编译阶段就可以确定函数的调用地址,并产生代码,就是静态多态(编译时多态)

动态多态:调用地址不能编译不能在编译期间确定,而需要在运行时才能决定,这这就属于晚绑定(动态多态,运行时多态)

发生多态的四个条件:

        父类中有虚函数

        必须发生继承

        子类必须重写虚函数(函数名 参数 返回值一致 函数的内容可以不一致)

        父类的指针或引用指向子类的对象

#include <iostream>

using namespace std;

class Animal
{
    public:
		virtual void speak()
		{
			cout << "动物在说话" << endl;
		}
};
class Dog:virtual public Animal
{
    public:
		//重写虚函数 函数的返回值 参数 函数名一样
		void speak()
		{
			cout << "狗在说话" << endl;
		}
};
class Cat:virtual public Animal
{
    public:
		//重写虚函数 函数的返回值 参数 函数名一样
		void speak()
		{
			cout << "猫在说话" << endl;
		}
};
//如果两个类发生了继承 父类和子类编译器都会自动转换 不需要人为转换
void do_work(Animal &obj)//多态接口 一个函数实现不同功能
{
	obj.speak();//地址早绑定->加上函数前面加上virtual 地址晚绑定
}

void test01()
{
	Animal p1;
	do_work(p1);//动物

	Dog p2;
	do_work(p2);//狗
	
	Cat p3;
	do_work(p3);//猫
}

int main()
{
    test01();
    return 0;
}

多态实现计算器案例

#include <iostream>
using namespace std;

class Calc
{
    public:
		virtual int mycalc(int a,int b)
		{
			return 0;		
		}
};
		
class Add:public Calc
{
    public:
		int mycalc(int a,int b)
		{
			return a + b;		
		}

};
class Mul:public Calc
{
    public:
		int mycalc(int a,int b)
		{
			return a * b;		
		}

};
class Sub:public Calc
{
    public:
		int mycalc(int a,int b)
		{
			return a - b;		
		}

};
		
int do_calc(int a,int b,Calc &obj)
{
	return obj.mycalc(a,b);
}

void test01()
{
	Add p1;
	cout << do_calc(3,4,p1) << endl;
	
	Mul p2;
	cout << do_calc(3,4,p2) << endl;

	Sub p3;
	cout << do_calc(3,4,p3) << endl;

}

int main()
{
    test01();
    return 0;
}

c++如何实现动态绑定

为什么可以根据传入对象的不同来执行不同的语句?

纯虚函数和抽象类

纯虚函数:将虚函数等于0 实质是将虚函数 表的函数入口设为NULL

抽象类:一个类如果有纯虚函数,那么这个类就是一个抽象类,抽象类不能实例化对象

继承抽象类的子类也是一个抽象类,如果子类重写了虚函数,那么子类就不是抽象类

class Calc
{
    public:
        virtual int mycalc(int a,int b) = 0;//虚函数等于0 纯虚函数
};

class Mob:public Calc
{
    public:
          //子类继承了抽象类 子类也是抽象类
           //如果子类重写虚函数 就不是抽象类
};

//如果有纯虚函数的类 叫做抽象类 抽象类无法实例化对象
void test()
{
    //Cacl p;//错误 
    Mod p1;
}

纯虚函数和多继承

多继承带来了一些争议,但是接口继承可以说一种毫无争议的运用了。
绝大数面向对象语言都不支持多继承,但是绝大数面向对象对象语言都支持接口的概念, c++ 中没有接口的概念, 但是可以通过纯虚函数实现接口。
接口类中只有函数原型定义,没有任何数据定义。
多重继承接口不会带来二义性和复杂性问题。接口类只是一个功能声明,并不是功能实现,子类需要根据功能说 明定义功能实现。
注意 : 除了析构函数外,其他声明都是纯虚函数。

虚析构函数

虚析构函数作用

在调用基类的析构函数之前,先调用子类的析构函数

#include <iostream>

using namespace std;

class Animal
{
    public:
		virtual void speak()
		{
			cout << "动物在说话" << endl;
		}
		virtual ~Animal()
		{
			cout << "动物的析构" << endl;
		}
};
class Dog:virtual public Animal
{
    public:
		//重写虚函数 函数的返回值 参数 函数名一样
		void speak()
		{
			cout << "狗在说话" << endl;
		}
		~Dog()
		{
			cout << "狗的析构" << endl;
		} 
};
class Cat:virtual public Animal
{
    public:
		//重写虚函数 函数的返回值 参数 函数名一样
		void speak()
		{
			cout << "猫在说话" << endl;
		}
};
//如果两个类发生了继承 父类和子类编译器都会自动转换 不需要人为转换
void do_work(Animal &obj)//多态接口 一个函数实现不同功能
{
	obj.speak();//地址早绑定->加上函数前面加上virtual 地址晚绑定
}

void test01()
{
	Animal *p = new Dog;
	p->speak();//调用狗的speak
	delete p;//加virtual 调用动物的析构 加virtual之后先调用狗的析构 再调用动物的析构
}

int main()
{
    test01();
    return 0;
}

纯虚析构函数

虚构函数等于零

class Animal
{
    public:
        virtual void speak()
        {
            cout << "动物在说话" << endl;
        }
        virtual ~Animal() = 0;//
};

重载 重定义 重写

重载:

        函数名相同

        同一个作用域

        参数的个数、顺序、类型不一致

        const也可以成为重载的条件

重定义:

        发生继承

        子类和父类有同名的变量和函数,父类中同名的变量和函数会被隐藏

重写:

        父类中有虚函数

        发生了继承

        子类重写了虚函数

        函数名返回值参数一致,函数体不一致

更多推荐

如何进行网络编程?

网络编程是计算机科学领域中的一个重要主题,允许计算机之间通过网络进行通信和数据交换。在C语言中,网络编程通常涉及使用套接字(socket)API来创建、连接、发送和接收网络数据。本文将介绍如何进行基本的网络编程,包括创建套接字、建立连接、发送和接收数据,以帮助C语言初学者入门这一领域。1.套接字(Socket)简介套接

排序算法:计数排序

前文说到,19591959年77月,希尔排序通过交换非相邻元素,打破了O(n^2)的魔咒,使得排序算法的时间复杂度降到了O(nlogn)级,此后的快速排序、堆排序都是基于这样的思想,所以他们的时间复杂度都是O(nlogn)。那么,排序算法最好的时间复杂度就是O(nlogn)吗?是否有比O(nlogn)级还要快的排序算法

Netty面试题(二)

文章目录前言一、Netty的线程模型?二、TCP粘包/拆包的原因及解决方法?三、了解哪几种序列化协议?总结前言Netty的线程模型?TCP粘包/拆包的原因及解决方法?了解哪几种序列化协议?一、Netty的线程模型?Netty通过Reactor模型基于多路复用器接收并处理用户请求,内部实现了两个线程池,boss线程池和w

合肥先进光源国家重大科技基础设施项目及配套工程启动会纪念

合肥先进光源国家重大科技基础设施项目及配套工程启动会纪念卡西莫多合肥长丰岗集里肥鸭从此别泥塘先平场地设围栏进而工地筑基忙光阴似箭指日争源流汇智山水长国器西北扩新地家校又添新区园重器托举有群力大步穿梭两地间科教兴邦大国策技术盈身坦荡行基坑从今开挖砌础柱继而深潜立设计蓝图逐展开施工巧匠刻惊奇项颈昂起躲绞索目光如炬细察析及时

数据库小记-mysql-DDL、DML、DQL

MySQL是一个流行的关系型数据库管理系统,支持各种数据库操作语言(DataManipulationLanguage,DML)、数据库定义语言(DataDefinitionLanguage,DDL)和数据查询语言(DataQueryLanguage,DQL)。以下是它们的主要区别和示例:DDL(数据定义语言):DDL用

【youcans动手学模型】目标检测之 SPPNet 模型

欢迎关注『youcans动手学模型』系列本专栏内容和资源同步到GitHub/youcans【youcans动手学模型】目标检测之SPPNet模型1.SPPNet卷积神经网络模型1.1论文摘要1.2技术背景1.3空间金字塔池化1.4目标检测1.5总结2.在PyTorch中定义SPP模型类2.1SPP层的参数计算2.2定义

AI实战营第二期 第五节 《目标检测与MMDetection》——笔记6

文章目录摘要主要特性常用概念框、边界框交并比(loU)感受野有效感受野置信度目标检测的基本思路难点滑框在特征图进行密集计算边界框回归基于锚框VS无锚框NMS(非极大值抑制)使周密集预测模型进行推理步骤如何训练密集预测模型的训练匹配的基本思路密集检测的基本范式多尺度预测如何处理尺度问题基于锶框(Anchor)图像金字塔I

【需求侧响应】综合能源中多种需求响应——弹性电价、可平移及可削减研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1概述📚2运行结果🎉3参考文献🌈4Matlab代码及数据💥1概述需求侧响应是一种通过调整能源消费行为以适应电网需

高比例清洁能源接入下计及需求响应的配电网重构(matlab代码)

1主要内容该程序复现《高比例清洁能源接入下计及需求响应的配电网重构》,以考虑网损成本、弃风弃光成本和开关操作惩罚成本的综合成本最小为目标,针对配电网重构模型的非凸性,引入中间变量并对其进行二阶锥松弛,构建混合整数凸规划模型,采用改进的IEEE33节点配电网进行算例仿真,分析了需求响应措施和清洁能源渗透率对配电网重构结果

基于yolov5的交通标志牌的目标检测研究——源码及文档

有需要本项目的全套代码和资源以及部署的可以私信博主!!!!!此外本项目所需的深度学习环境点击顶部即可下载,解压可以使用,直接跑所有的深度学习模型,超级方便!本课题研究,通过利用提供的公开数据集TT100K图标进行筛选和整理,最终得到TT100K数据中的45类交通标志牌数据。并将数据集进行分割,其中训练集:6664条;验

FFmpeg5.1.3编译动态库详细教程(基于Linux虚拟机)

FFmpeg编译详细教程FFmpeg编译详细教程本文原创:猿视野(一家分享技术架构思路,扩展程序员视野的网站,遇到技术问题,可以加联系方式相互交流)转载请注明出处和相关链接,否则追究其法律责任!原文地址:https://developer.aliyun.com/article/1326862?source=5176.1

热文推荐