C++:多态详解

一、多态怎么实现的?

多态按字面的意思就是多种形态,相同的方法调用,但是有不同的实现方式(多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,这样就可以用同一个函数名调用不同内容的函数)。多态性可以简单地概括为“一个接口,多种方法”。C++有两种多态形式:静态多态和动态多态。

在C++中,多态性的实现和联编(也称绑定)这一概念有关。一个源程序经过编译、链接,成为可执行文件的过程是把可执行代码联编(或称装配)在一起的过程。其中在运行之前就完成的联编成为静态联编(前期联编、地址早绑定);而在程序运行之时才完成的联编叫动态联编(后期联编、地址晚绑定)。一般说的多态指的是动态多态。

静态多态和动态多态区别:
a. 静态绑定又称为前期绑定(早绑定),在程序编译期间确定了程序的行为,也称为静态多态 ,静态多态的函数地址早绑定 - 编译阶段确定函数地址,例如:函数重载。
b. 动态绑定又称为后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态,动态多态的函数地址晚绑定 - 运行阶段确定函数地址。

C++的多态性用一句话概括就是:1、在基类的函数前加上virtual关键字,2、在派生类中重写该函数,3、运行时采用父类的引用和指针调用多态方法,父类对象本身不能实现多态。

class animal
{
public:
	virtual void sleep()	//父类虚函数
	{
		cout << "animal sleep" << endl;
	}
	void breathe()			//父类非虚成员函数
	{
		cout << "animal breathe" << endl;
	}
};
class fish :public animal
{
public:
	void sleep(int time)	//父类同名函数隐藏(子类重写时参数和父类虚函数不同)
	{
		cout << "fish sleep " << time << " hours" << endl;
	}
	void breathe()			//父类同名函数隐藏(父类非虚函数)
	{
		cout << "fish bubble" << endl;
	}
};
class cat :public animal
{
public:
	void sleep()			//子类重写父类虚函数
	{
		cout << "cat sleep" << endl;
	}
	void sleep(int time)	//父类指针或引用无法访问
	{
		cout << "cat sleep " << time << " hours" << endl;
	}
	void breathe()			//子类重写父类非虚函数
	{
		cout << "cat miaomiao" << endl;
	}
};


int main() {
	animal a;
	a.breathe();		//调用animal中的breathe()
	fish f;
	//f.sleep();		//报错
	f.sleep(5);
	f.breathe();		//调用fish中的breathe(),实际上是函数隐藏
	cat c;
	c.sleep();
	c.sleep(5);			//函数重载
	c.breathe();
	animal *p = &c;
	p->sleep();			//父类指针指向子类对象,动态多态,调用了子类对象cat中的sleep()
	//p->sleep(5);		//报错,无法调用
	animal &p1 = c;		//父类引用子类对象,动态多态,调用了子类对象cat中的sleep()
	//p1.sleep(5);		//报错,无法调用
	animal *p2 = &f;
	p2->sleep();		//调用父类animal中的sleep()
	//p2->sleep(5);		//报错,无法调用
	system("pause");
	return 0;
}

1、函数的覆盖(重写)
覆盖的条件:
基类函数必须是虚函数(使用Virtual关键字进行声明);
发生覆盖的两个函数必须分别位于派生类和基类中;
函数名称与参数列表必须完全一样;
2、函数的重载
函数重载是同一定义域中(即同一个类中)的同名函数,但形参的个数必须不同,包括参数个数,类型和顺序,不能仅通过返回值类型的不同来重载函数。const也可作为函数重载的条件,但只有引用传递和指针传递可以用是否加const来重载。
3、函数的隐藏
隐藏,是指派生类中具有与基类同名的函数(不考虑参数列表是否一样),从而派生类中隐藏了基类的同名函数。
隐藏的两种情况:
① 派生类的函数与基类的函数完全相同(函数名和参数列表都相同),只是基类的函数没有使用virtual关键字。
② 派生类的函数和基类的函数同名,但参数列表不一样,在这种情况下,不管基类的函数声明是否有virtual关键字,基类的函数都将被隐藏。(注意这种情况与函数重载的区别,重载发生在同一个类中)
多态中的注意点:
1:用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。

2:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。

3:多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。

4:多态用虚函数来实现,结合动态绑定.

5:纯虚函数是虚函数再加上 = 0;

6:抽象类是指包括至少一个纯虚函数的类。(纯虚函数:virtual void fun()=0;即抽象类!必须在子类实现这个函数,即先有名称,没有内容,在派生类实现内容。)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值