Bootstrap

【C++学习笔记 11】C++中的接口(纯虚函数)

什么是纯虚函数

原理上来讲,纯虚函数允许我们定义一个在基类中没有实现的函数,然后强制在子类中去实现这个函数。如果在基类中的虚函数带有实际函数体,那么在子类中重写函数是可写可不写的,这时调用的就是基类中的函数体。然而,在有些场景中,提供默认的函数体没有意义,实际上的需求只是强制子类为某个特定的函数提供自己的定义。

在面向对象的程序设计中,创建一个只包含未实现的方法然后让子类去实现实际功能的做法非常普遍,这一般被称为接口(interface),即一个只包含未实现的方法并作为一个模板的类。由于接口类不包含方法实现,因此无法实例化这个类。

举个例子

先以上一张笔记中的例子为基础,将虚函数的函数体删去,并写=0 ,这样就将虚函数变为纯虚函数

#include <iostream>
#include <string>

class Entity
{
public:
	virtual std::string Getname() = 0;
};
class Player : public Entity
{
private:
	std::string m_Name;
public:
	Player(const std::string& name) //constructor
		: m_Name(name){}
	std::string Getname() override { return m_Name; }
};

在上述基础上进行修改,创建Printable类及其纯虚函数,然后分别在Entity中和Player中各自实现,这样就包含了纯虚函数与虚函数两种用法。

#include <iostream>
#include <string>
class Printable
{
public:
	virtual std::string GetClassName() = 0;
};

class Entity : public Printable
{
public:
	virtual std::string Getname() { return "Entity"; }
	std::string GetClassName() override { return "Entity"; }
};
class Player : public Entity
{
private:
	std::string m_Name;
public:
	Player(const std::string& name) //constructor
		: m_Name(name){}
	std::string Getname() override { return m_Name; }
	std::string GetClassName() override { return "Player"; }
};

void Print(Printable* obj)
{
	std::cout << obj->GetClassName() << std::endl;
}

int main()
{
	Entity* e = new Entity();
	Player* p = new Player("InfiHeart");
	Print(e);
	Print(p);
	std::cin.get();
}

教程来源:The Cherno C++ 教程

;