C++多态

吃可爱长大的小学妹 提交于 2020-01-13 02:59:38

静态多态:函数重载和运算符重载
静态多态也叫函数地址早绑定,在编译阶段确定函数地址。

动态多态

动态多态满足条件:

  • 有继承关系
  • 子类重写父类的虚函数

多态的使用:()\color{red} 父类的指针或引用指向(接收)子类对象
空类大小是1个字节
加上virtual后变成4字节,本质是一个()\color{red} 虚函数(表)指针vfptr指向虚函数表,表内记录虚函数的地址。子类继承虚函数指针以后,在自己的空间也复制了一份虚函数表,如果重写了虚函数,则在虚函数表中替换掉父类中的虚函数地址。

#include <iostream>
using namespace std;
class Animal{
public:
	 virtual void speak(){
		cout<<"动物在说话"<<endl;
	}
};
class Cat: public Animal{
	public:
	void speak(){
		cout<<"猫在说话"<<endl;
	}
};

void dospeak(Animal &animal){
	animal.speak();
}
int main(){
	Cat cat;
	dospeak(cat);
	return 0;
} 

多态的优点

  • 组织结构清晰
  • 可读性强
  • 对于前期或后期扩展性高

纯虚函数

有纯虚函数的类叫做抽象类。
抽象类的特点

  • 无法实例化对象
  • 子类需要重写父类的纯虚函数,否则子类也是抽象类
virtual void disp()=0;

纯虚析构和虚析构

相同点

  • 都需要声明并实现
  • 都可以解决父类无法调用子类析构函数的问题。

不同点

  • 如果是纯虚析构,则该类属于抽象类,无法实例化对象。
virtual ~Animal()=0;  //纯虚析构
/*类外实现*/
Animal::~Animal(){//具体析构实现
}

\color{red}如果子类中没有堆区数据,可以不写为虚析构或纯虚析构

override

如果我们使用override标记了某个函数,但是该函数并没有覆盖父类中的虚函数,此时编译器将会报错。
\color{red}必须针对虚函数,此时我们希望的是对父类虚函数的重写或者说覆盖而不是重载,所以覆盖时参数返回值必须完全相同

final

一个类,如果不希望其他类继承它,必须在类名后跟一个final关键字

class Base final{}; //类不能再被继承
class B{};
class Last final: B {}; //该类不能再被继承
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!