c++面对对象多态上(复习)

一、函数的扩展性

1.  函数调⽤时必须严格匹配类型
2.  如果类型不符,编译器会进⾏隐式类型转换,如果能转换成⽬标类型,则调⽤成功,如果⽆法转
换为⽬标类型,则调⽤失败。
3.  C++中如果参数接收的是基类类型,那么派⽣类对象可以作为参数传递。

在开发中一定要注意函数的扩展性,也就是函数功能的单一化 确保一个函数只干一件事情
为什么要这么做,一是为了以后进行函数重载时,方便在原有的函数功能上去拓展新的功能
二是避免BUG的寻找难度 如果一个函数内封装多个功能,那么很有可能出问题时需要将整个函数重写。一个功能带来的bug会影响整个函数,所以开发时一定要保证函数功能的单一化

二、静态和动态绑定

先看一个错误代码

class  Animal
{
public:
	void  speak(){
		cout  <<  "说话..."  <<  endl;
	}
};
class  Cat  :  public  Animal
{
public:
	void  speak(){
		cout  <<  "⼩猫说话..."  <<  endl;
	}
};
class  Dog  :  public  Animal
{
public:
	void  speak(){
		cout  <<  "⼩狗说话..."  <<  endl;
	}
};
void  do_speak(Animal  &obj){
	obj.speak();
}
void  test(){
	Animal  animal;
	do_speak(animal);
	Cat  cat;
	do_speak(cat);
	Dog  dog;
	do_speak(dog);
}
输出结果是
说话...
说话...
说话...

没有出现我们想出现的情况 是因为绑定的问题
函数体与函数调⽤相联系称为绑定

1.  如果这个绑定发⽣在程序运⾏之前,也就是编译阶段,称作早绑定,静态绑定。
2.  如果这个绑定并不在编译阶段进⾏,⽽是在运⾏过程中,根据实际情况进⾏绑定,称作晚绑定,
动态绑定。

问题就是由于静态绑定引起的,编译器只有知道Animal 地址时并不知道调⽤的正确函数,所以根据对象指针、引⽤的类型 来选择函数调⽤。

解决办法:就是让编译器进⾏动态绑定,⽽不是在编译阶段进⾏函数调⽤绑定。在 C语⾔中所有的函数绑定都是静态绑定,在 C++通过虚函数 (virtual function)机制来实现动态绑定。

通过创建⼀个 virtual函数来告诉编译器该函数要进⾏动态绑定,编译器就会根据动态绑定机制来实现
我们的要求,不会再执⾏静态绑定。
实现动态绑定,步骤如下:

1.  将函数参数设置为基类指针、或者基类引⽤。
2.  将基类中希望进⾏动态绑定的函数声明为虚函数。
3.  在⼦类中将基类虚函数重写。
注意:
1.  ⼀旦在基类中将函数声明为虚函数,在此后所有的派⽣类中该函数都将是虚函数。
2.  virtual只能修改成员函数。
3. 构造函数不能声明使⽤ virtual声明。
class  Animal
{
public:
	virtual  void  speak(){
		cout  <<  "说话..."  <<  endl;
	}
};
class  Cat  :  public  Animal
{
public:
	void  speak(){
		cout  <<  "⼩猫说话..."  <<  endl;
	}
};
class  Dog  :  public  Animal
{
public:
	void  speak(){
		cout  <<  "⼩狗说话..."  <<  endl;
	}
};
void  do_speak(Animal  &obj){
	obj.speak();
}
void  test()
{
	Animal  animal;
	do_speak(animal);
	Cat  cat;
	do_speak(cat);
	Dog  dog;
	do_speak(dog);
}
输出结果:
	说话...
	⼩猫说话...
	⼩狗说话...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值