C++之多态

本文介绍了C++中的多态概念,包括什么是多态、如何使用多态、虚函数的重写(覆盖)、多态的实现原理、抽象类的作用以及不是所有函数都能成为虚函数的原因。多态是通过虚函数和虚函数表实现,要求对象必须是引用或指针,且虚函数必须被重写。抽象类则强制派生类完成虚函数的重写,提供接口继承关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多态的知识有以下几点

 

1.什么是多态?

     简单来说就是不同的对象去完成同一个行为会产生不同的结果。

举个例子:国庆去华山游玩,一般的成人要买全价票,而我们学生买票买学生票。这就是两种不同的对象都去买票但是产生的结果却不同,一个是全价票一个是学生票。

 

2.如何使用多态?

使用多态有两个前提条件

1.调用函数的对象必须是指针或者引用

2.调用的函数必须是虚函数,而且完成了虚函数的重写

class Person
{
public:
	virtual void BuyTicket()
	{
		cout << "全价票" << endl;
	}
};
class Student : public Person
{
public:
	virtual void BuyTicket()
	{
		cout << "学生票" << endl;
	}
};
void Fun(Person & p)
{
	p.BuyTicket();
}

那么为什么要是对象的指针或引用?

什么又是虚函数?什么又是虚函数的重写?

 

3.虚函数的重写(覆盖)

虚函数:

   所谓的虚函数就是在函数前面加上virtual这个关键字。那么他就成为了虚函数。

虚函数的重写:

   派生类中有一个跟基类的完全相同虚函数,我们就称子类的虚函数重写了基类的虚函数,完
全相同是指:函数名、参数、返回值都相同。另外虚函数的重写也叫作虚函数的覆盖。

正因为完成了虚函数的重写,才会产生不同的行为,所以这是多态的两个必要条件之一。

 

4.多态的原理

多态是如何实现的呢?

class Person
{
public:
	virtual void BuyTicket()
	{
		cout << "全价票" << endl;
	}
	int a;
};

int main()
{
	Person p;

	return 0;
}

这个类里只有一个成员变量A。我们通过调试查看监视

我们发现不仅仅是一个成员变量还有一个_vfptr。

他是一个隐藏的指针,叫虚函数表指针,他指向了虚函数表的地址,虚函数表里存放的都是虚函数的地址。

我们可以看到BuyTicket这个函数的地址就是_vfptr[0]的值。

 

再次结合一段代码来看一下关于虚函数的继承关系

class A
{
public:
	virtual void Fun1()
	{
		cout << "Fun1-A" << endl;
	}
	virtual void Fun2()
	{
		cout << "Fun2-A" << endl;
	}
        void Fun3()
	{
		cout << "Fun3-A" << endl;
	}
};
class B : public A
{
public:
	virtual void Fun1()
	{
		cout << "Fun1-B" << endl;
	}
}

A类中有两个虚函数,一个普通函数,B类继承了A类且只对Fun1完成了重写

再次观察,我们发现B类继承了A类,b也有虚函数表,因为对Fun1完成了重写,我们可以发现两个类的Fun1的地址是不相同的。

而Fun2是直接继承的,没有完成重写,所以我们可以看到他们的地址是相同的。

并且我们发现Fun3没有在虚表里出现,也就是说只有虚函数才会被放进虚函数表,普通函数不会。

 

多态就是通过传参找到对象,然后去对应对象的虚表中找到对应的虚函数调用。

所以必须传指针或者引用,不能传值,并且必须完成虚函数的重写。只有完成了重写才能实现出不同的对象完成同一行为,产生不同的结果。

 

5.抽象类:

介绍抽象类之前我们先了解一下纯虚函数

virtual void Fun1() = 0
	{
		cout << "Fun1-A" << endl;
	}

这就是纯虚函数在虚函数后面加上 =0 就是纯虚函数

抽象类就是由纯虚函数实现的。

抽象类的特点:

抽象类无法实例化出对象,派生类也无法实例化出对象,只有当派生类完成了虚函数的重写,才能实例化出对象。

这样就意味着强制我们派生类完成虚函数的重写,不然不能使用,这样的好处就是防止出现无用的虚函数。抽象类体现了接口继承关系。

 

了解完上面的知识,我们最后在了解一下有关虚函数的问题。

6.所有函数都可以是虚函数吗?

答案是NO。

1.首先内联函数无法成为虚函数,因为我们都知道虚函数的地址放在虚表里面,而内联函数没有地址,没有地址就没有办法放进虚表,所以不行。

2.静态成员函数也不行,因为静态成员函数没有this指针,使用类型::成员函数的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。

3.构造函数也不能成为虚函数,因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的。

 

 

 

 

 

 

 

          

内容概要:本文档详细介绍了Analog Devices公司生产的AD8436真均方根-直流(RMS-to-DC)转换器的技术细节及其应用场景。AD8436由三个独立模块构成:轨到轨FET输入放大器、高动态范围均方根计算内核和精密轨到轨输出放大器。该器件不仅体积小巧、功耗低,而且具有广泛的输入电压范围和快速响应特性。文档涵盖了AD8436的工作原理、配置选项、外部组件选择(如电容)、增益调节、单电源供电、电流互感器配置、接地故障检测、三相电源监测等方面的内容。此外,还特别强调了PCB设计注意事项和误差源分析,旨在帮助工程师更好地理解和应用这款高性能的RMS-DC转换器。 适合人群:从事模拟电路设计的专业工程师和技术人员,尤其是那些需要精确测量交流电信号均方根值的应用开发者。 使用场景及目标:①用于工业自动化、医疗设备、电力监控等领域,实现对交流电压或电流的精准测量;②适用于手持式数字万用表及其他便携式仪器仪表,提供高效的单电源解决方案;③在电流互感器配置中,用于检测微小的电流变化,保障电气安全;④应用于三相电力系统监控,优化建立时间和转换精度。 其他说明:为了确保最佳性能,文档推荐使用高质量的电容器件,并给出了详细的PCB布局指导。同时提醒用户关注电介质吸收和泄漏电流等因素对测量准确性的影响。
内容概要:本文档介绍了一种基于ADP5070 DC-DC开关稳压器、ADP7142和ADP7182 CMOS LDO线性稳压器、LC滤波器及电阻分压器的电路设计方案,旨在为仅拥有5 V单电源的系统提供低噪声、双电源解决方案,以支持AD5761R双极性DAC的工作。AD5761R是一款16位双极性DAC,需要双电源来提供双极性输出电压范围。文中详细描述了如何配置该电路以适应单电源系统的应用,并展示了不同电源配置(包括外部电源、ADP5070和LC滤波器、ADP5070和LDO线性稳压器)下的性能测试结果,特别是频谱分析、输出电压噪声和交流性能等方面的数据。测试结果表明,增加LDO线性稳压器可以显著降低输出噪声,提升整体性能。 适合人群:从事精密仪器设计、数据采集系统开发的技术人员,尤其是那些需要理解和应用低噪声电源解决方案的专业人士。 使用场景及目标:适用于需要从单一5 V电源生成双电源的应用场合,如测试与测量设备、数据采集系统、执行器控制系统和工业自动化等领域。主要目标是在保证低噪声的前提下,确保AD5761R DAC能够在单电源环境中正常工作,提供高质量的双极性输出。 其他说明:本文档不仅提供了详细的电路配置指南,还通过大量的图表和数据分析验证了不同电源配置的效果。特别强调了在不同频率范围内,使用内部基准电压源和外部基准电压源(如ADR4525)对DAC输出噪声的影响。此外,文档还讨论了LC滤波器和LDO线性稳压器在减少开关纹波方面的作用,为实际应用提供了有价值的参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值