C++关于多态的解析

众所周知C++是一种面向对象的语言,它相较于C语言还是主要它的封装、继承、多态;今天我们就来说说它的多态。

多态是什么呢?说白了就是同一操作,用作不同对象,可以产生不同的效果。

关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。

然后有人就要问了,那多态有什么用呢?多态其实可以减少代码量。比如你要一个不同子类产生不同的效果,那你是不是要先去判断这个对象应该用哪个函数,那你是不是要不停的if来判断,但是使用多态就可以合理的解决这个问题了。

多态分为静多态(函数重载,模板)和动多态(虚函数)

静多态:在编译器的编译期间完成,编译器根据实参类型来选择调用合适的函数,如果有合适的函数就调用,没有就发出警告或报错。

动多态:实在程序运行时根据基类的引用(指针)指向的对象1确定自己具体应该调用哪个类的虚函数

动多态的条件:

       基类必须包含虚函数,并且派生类中一定要对基类的虚函数进行重写

       通过基类对象的指针或者引用调用虚函数

函数重载:重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个函数完成不同的功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。不能只有函数返回值类型不同。

函数模板:函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。

我们今天主要来说说虚函数:虚函数其实就是对函数的重写,要求函数名,函数类型,参数个数和参数类型相同,但析构函数可以不同,析构函数在底层其实也会将函数名同步。

下面我们来说说虚函数表:对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。

至于有人不太懂这个虚函数表,虚函数指针,什么的,给你一张图你就清楚了

在这里还有必要说说纯虚函数,纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”

为什么会有纯虚函数呢?

1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。

为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。它的存在就是为了被继承,这样就很好地解决了上述两个问题。

下面附上多态的代码,可以看代码来了解这些东西

#include<iostream>
using namespace std;
//class Person
//{
//public:
//	virtual void BuyTicket() { cout << "免票-全价" << endl; }
//};
//class Student:public Person
//{
//public:
//	virtual void BuyTicket() { cout << "免票-半价" << endl; }
//
//};
//void Func(Person& p)
//{
//	p.BuyTicket();
//}
//int main()
//{
//	Person ps;
//	Student st;
//	Func(ps);
//	Func(st);
//	return 0;
//
//}
/////////////////////////////////
//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;
//	return 0;
//
//}
/////////////////////纯虚函数不能实例化对象,必须被重写
//class car
//{
//public:
//	virtual void Drive();
//};
//class benz :public car
//{
//	//virtual void Drive()override
//	virtual void Drive()
//	{
//		cout << "舒适" << endl;
//	}
//};
//class bmw :public car
//{
//	virtual void Drive()
//	{
//		cout << "操控" << endl;
//	}
//};
//void Test()
//{
//	car* p = new benz;
//	p->Drive();
//	car* p1 = new bmw;
//	p1->Drive();
//
//
//}
//int main()
//{
//	Test();
//	return 0;
//}
//override 修饰派生类虚函数强制完成重写
class Base
{
public:
	virtual void Func1()
	{
		cout << "Base::Func1()" << endl;
	}
	virtual void Func2()
	{
		cout << "Base::Func2()" << endl;
	}
	void Func3()
	{
		cout << "Base::Func3()" << endl;
	}
private:
	int _b = 1;
};
class Derive : public Base
{
public:
	virtual void Func1()
	{
		cout << "Derive::Func1()" << endl;
	}
private:
	int _d = 2;
};
//void Test(Base &p)
//{
//	p.Func1();
//}
int main()
{
	Base b;
	b.Func1();
	Derive d;
	d.Func3();
	return 0;
}
//不构成多态

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值