C++进阶:多态(三)

316 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

💦 C++11 final和override

✔ 测试用例一:

class A final
{};
class B : public A
{};

int main()
{
	return 0;
}
#include<iostream>
using namespace std;

class Car
{
public:
	virtual void Drive() final 
	{}
};
class Benz : public Car
{
public:
	virtual void Drive() 
	{ 
		cout << "Benz-舒适" << endl; 
	}
};

int main()
{
	return 0;
}
  • final 修饰类,表示该类不能再被继承。同样是实现出一个不能被继承的类,C++11 中的 final 相对 C++98 中对构造函数私有化更为彻底。

    在这里插入图片描述

  • final 修饰虚函数,表示该虚函数不能再被重写,重写则会报错。

    在这里插入图片描述

✔ 测试用例二:

#include<iostream>
using namespace std;

class Car 
{
public:
	virtual void Drive() {}
};
class Benz : public Car 
{
public:
	//virtual void Drive() override//ok,重写 
	//{ 
	//	cout << "Benz-舒适" << endl; 
	//}

	//void Drive() override//ok,属于重写的例外
	//{ 
	//	cout << "Benz-舒适" << endl; 
	//}

	virtual void Drive(int) override//err,没有完成重写
	{
		cout << "Benz-舒适" << endl;
	}
};
int main()
{
	return 0;
}
  • override 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写则编译报错。

    在这里插入图片描述

💦 重载、重定义(隐藏)、重写(覆盖)的对比

在这里插入图片描述

💦 抽象类概念

✔ 测试用例三:

#include<iostream>
using namespace std;

class Car//抽象类
{
public:
	virtual void Drive() = 0;//纯虚函数
};
class Benz : public Car
{
public:
	virtual void Drive()//重写纯虚函数
	{
		cout << "Benz-舒适" << endl;	
	}
};
class BMW : public Car
{
public:
	virtual void Drive()//重写纯虚函数
	{
		cout << "BMW-操控" << endl;
	}
};

int main()
{
	Benz bz;

	Car* pBenz = new Benz;
	pBenz->Drive();

	Car* pBMW = new BMW;
	pBMW->Drive();	

	return 0;
}
  • 在虚函数的后面写上 = 0,则这个函数为纯虚函数,包含纯虚函数的类叫做抽象类 (也叫接口类,你可以模糊的认为一个类的公有成员函数是接口,但更多是因为纯虚函数只有声明,没有实现,所以叫接口类。通常还是叫抽象类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象,也就是说纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。

    理解接口类和抽象类 ❓

      接口类相比抽象类的概念更广泛,你可以认为一个类的公有成员函数是接口,换一个角度,如果一个类设计的不规范,也不能说公有的成员函数就是接口。但更重要的是纯虚函数只有声明,没有定义,所以有些地方叫接口类。这个概念比较模糊,但是也要能理解有些地方叫接口类,但是更重要的还是要理解它叫抽象类。

      抽象这个词,我们理解的场景是 “ 你长的好抽象 ” 或 “ 抽象派画家画的画好抽象 ”。本质抽象类指的是在现实世界中没有具体的对应实物,也就没必要实例化对象,比如说车去实例化对象,那么对象是卡车、公交车还是观光车?车是抽象的,它实例化的对象没有具体对应实物,所以我们可以把它实现为抽象类,让它不能实例化对象。

  • 抽象类可以创建指针,但是只能指向子类,因为父类不能创建对象。

💦 接口继承和实现继承

  • 这个概念了解下,有些书上会提,主要是为了避免以后遇到了不知道它讲的啥。
  • 普通函数的继承是一种实现继承,派生类继承了基类,可以使用函数,继承的是函数的实现。虚函数的继承是接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达到多态,继承的是接口。所以不实现多态,不要把函数定义成虚函数。