C++中的多态【详细讲解】

1、多态的概念【重点】

  • 同一操作(函数)作用于不同的对象(不同类实例化的对象),可以有不同的解释,产生不同的执行结果。【重点理解记忆】

  • 在运行时,可以通过指向【基类的指针或者引用】,来调用实现派生类中的方法(派生类中的函数)。

2、虚函数(小重点,可以实现多态的关键)

1)虚函数是动态绑定的基础。用于继承关系中,它是在基类定义的【成员函数】,而且是【非静态成员函数】。

2)格式:

virtual 函数类型 函数名称(参数表){函数体}

【使用virtual关键字修饰的函数称为虚函数。如果在【基类】中的成员函数被声明为虚函数,也就意味着他在派生类中可能有不同的实现

3)实例:

#include <iostream>
//多态的概念
//同一操作(函数)作用于不同的对象(不同类实例化的对象),可以有不同的解释,产生不同的执行结果

using namespace std;
//基类
class Person {
public:
	//成员函数
	virtual void Express_Love(void)  //使用虚函数
	{
		cout << "I Love You!" << endl;
	}
};
//派生类
class Chinese :public Person {
public:
	//成员函数
	void Express_Love(void)
	{
		cout << "俺稀罕你!" << endl;
	}
};
class Russia :public Person {
public:
	//成员函数
	void Express_Love(void)
	{
		cout << "Я цябе кахаю!" << endl;
	}
};
class Little_Japanese_devils :public Person {
public:
	//成员函数
	void Express_Love(void)
	{
		cout << "あなたのことが好きです!" << endl;
	}
};
//同一操作
void function(Person &a)//使用基类的引用----作用于不同的对象
                        //(注意这个地方这里是引用,如果不使用引用的话,会造成派生类隐含转换为基类的情况【具体讲解看第五章集成中的第9小节】)
{
	a.Express_Love();   //有不同的解释,产生不同的执行结果
}

int main()
{
	Chinese person;
	function(person);
	Russia person1;
	function(person1);
	Little_Japanese_devils person2;
	function(person2);
	return 0;
}

运行结果:

俺稀罕你!
Я цябе кахаю!
あなたのことが好きです!

3、多态原理讲解:【重点】

  • 当一个类中函数为虚函数时,该类实例化的对象存储就会在非静态成员的前面添加一个vfptr指针,该指针指向一个虚函数表,所以这个指针称为虚函数表指针。

  • 虚函数表中存放的是当前对象的所有虚函数的地址。

 (1)虚函数列表中存储结构为:【可以看出虚函数表中存放的都是基类中的函数地址派生类可以重写这些地址

long类型数组,以"\0"结尾;

(2)vfptr:有虚函数的对象有且只有一个vfptr指针,虚函数表中存放多个地址;

(3)虚函数表及vfptr是派生类对象的【基类产生的】--->派生类重写虚函数表内容【即重写地址】。

4、多态的条件

1)多态需要满足的条件:

  • 有继承关系;

  • 子类重写父类中的虚函数。

2)多态的使用条件:

父类的指针或者引用指向子类

4)多态重写的规则:

  • 派生类中定义与基类虚函数同名、同参数、同返回值的成员函数。

  • 在派生类中重新实现基类中的虚函数称为重写或覆盖。

  • 多态是动态绑定。

5)多态的好处

  • 将不同的子类对象都当做父类来看,可以写出通用代码。(一句话来概括:父亲的行为像儿子,而不是儿子的行为像父亲)

  • 【提倡开闭原则:对于扩展进行开放,对于修改进行关闭。】

实例:

#include <iostream>

using namespace std;
//基类
class Basic_A {
public:
	Basic_A(int a, int b) :A(a), B(b)   //构造函数+初始化列表
	{

	}
	//虚函数(实现一个加的功能)---通过派生类进行重写(覆盖写)
	virtual int Make()
	{
		
	}
protected:
	int A;
	int B;
};
//派生类
class Derive_ADD:public Basic_A {
public:
	//构造函数
	Derive_ADD(int a, int b): Basic_A(a,b)  //使用初始化列表来调用基类中的构造函数,进行赋值
	{

	}
	int Make()
	{
		return A + B;
	}

};
//派生类
class Derive_SUB:public Basic_A {
public:
	//构造函数
	Derive_SUB(int a, int b) : Basic_A(a, b)  //使用初始化列表来调用基类中的构造函数,进行赋值
	{

	}
	int Make()
	{
		return A - B;
	}
};
//派生类
class Derive_MUL :public Basic_A {
public:
	//构造函数
	Derive_MUL(int a, int b) : Basic_A(a, b)  //使用初始化列表来调用基类中的构造函数,进行赋值
	{

	}
	int Make()
	{
		return A * B;
	}
};
//派生类
class Derive_DIV :public Basic_A {
public:
	//构造函数
	Derive_DIV(int a, int b) : Basic_A(a, b)  //使用初始化列表来调用基类中的构造函数,进行赋值
	{

	}
	int Make()
	{
		return A / B;
	}
};

int main()
{
	//通过父类引用指向派生类
	Derive_ADD add(10,5);
	Basic_A& f = add;
	cout <<"通过引用:"<<f.Make() << endl;
	//通过父类的指针指向派生类
	Basic_A* p = new Derive_MUL(10, 5);
	cout <<"通过指针:"<<p->Make() << endl;
	return 0;
}

运行结果:

通过引用:15
通过指针:50

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值