C++的多态性

本文深入探讨C++中的多态性概念,包括其两种形式:编译时多态性和运行时多态性,并通过代码示例展示了如何利用虚函数实现多态。此外,文章还解释了纯虚函数及抽象类的作用。

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

  学习c++这么久,c++的几个特点:封装,继承,多态。

  封装很好理解,是面向对象程序设计语言的标志,把数据和函数封装在一起作为一个类的定义,对象就是类的一个实例化,类的实际内部都被隐藏起来,外部只需要通过实例化一个对象,然后通过对象调用类的内部成员函数就可以了,封装可以使得代码模块化,避免代码的重写;

  继承可以扩展已存在的代码,跟封装目的相同,都是为了代码重用,简单的定义一个父类,就可以使用父类的成员函数(分为公开,私有和受保护)而不用自己重新定义,非常方便;

  最让我纠结的是类的多态,一直说多态性,也会用,无非就是在父类定义一个虚函数,然后在子类中重定义这个函数,真正调用的时候还是通过子类的对象调用这个函数,于是一直不明白这个多态性强大在哪,今天好好研究了一下,才算有了点眉目。

  多态性分为2种,编译时多态性和运行时多态性。前者通过重载函数实现,后者通过虚函数实现。指相同的对象(父类对象)收到不同的消息(指向不同的子类)或者不同的对象(子类对象)接受相同的消息产生不同的实现动作。

  多态与非多态的实质区别就在于函数地址是早绑定还是晚绑定,即在编译期间函数调用的地址是编译时就确定就是早绑定,在运行时才能确定就是晚绑定。

  下面是一个很简单的测试栗子,继承无需多说,

  p->duotai();
  p->duotai1();


    这两句能很好的体现出多态的特点,p是父类的一个对象,如果他指向的也是一个父类的对象,那没什么好说的输出的调用的肯定是父类的成员函数,输出的是"parent duotai"。而如果父类指向的是子类的对象,则正体现了多态的用法。由于指针是个父类指针,在调用duotai1()的时候,调用的不是虚函数,而是指向一个固定偏移量的函数的时候(属于早绑定),调用的是父类的duotai1,输出的是"parent duotai1",而对于虚函数duotai(),每个虚函数都有一个虚函数列表,系统会根据指向对象的不同,通过函数序列找到相应对象的地址,调用对用的成员函数。

  总结来说,对于非虚函数,调用是根据对象属于哪一类,则调用哪一类的成员函数;而对于虚函数,则是根据对象指向的对象,指向哪个类的对象,则调用哪个类的成员函数,例如

B* ptr = (B*)&a;  
ptr->duotai();
ptr->duotai1();
B的一个对象虽然指向父类A,但是由于duotai1()不是虚函数,调用的时候还是调用的子类(B类)的函数,而对于虚函数duotai(),则调用的是指向的A类的成员函数。

#include"iostream"
using namespace std;
class A               
{
public:
	void jicheng()
	{
		cout<<"jicheng"<<endl;
	}
	virtual void duotai()
	{
		cout<<"parent duotai"<<endl;
	}
	void duotai1()
	{
		cout<<"parent duotai1"<<endl;
	}
};
class B:public A
{   
public:
	void duotai()
	{
		cout<<"child duotai"<<endl;
	}
	void duotai1()
	{
		cout<<"child duotai1"<<endl;
	}
};                                  


int main()
{
	B b;
	b.jicheng();
	A* p=&b;
	p->duotai1();
	p->duotai();
	return 0;
}
   最后,有一种特殊的虚函数是纯虚函数,在父类中是没有定义的,具体表现为 virtual void duotai()=0,对于纯虚函数,编译器要求在子类中必须重写以实现多态性。同时含有纯虚函数的类称为抽象类,不能生成对象。

   比如我定义了一个父类,动物类,这是一个抽象类,我在里面定义一个eatfood()的成员函数,每一个动物都要吃东西,再定义一个猴子类,猫类等继承动物类的子类,再各个子类下面都有一个eatfood()的函数,但是实现是不同的。系统会根据你指向对象的不同,调用不同的成员函数,产生不同的结果,既方便又明了。

   总体来说,多态的优点就是无论传递过来不的是哪个类的对象,函数都能够通过同一个接口调用适应各自对象的实现方法。

   参考:http://blog.youkuaiyun.com/hackbuteer1/article/details/7475622  ,纯手打,加上一些自己的理解,希望会对一些同样迷茫的人有点帮助。。

   成功之路,细节决定成败,

   看了网上这么多大神的帖子,真是觉得未来要走的路还很长。

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值