C++ 虚函数
虚函数
看下面这段代码:
#include <iostream>
using namespace std;
class Entity{
public:
void getName(){
cout << "Entity" << endl;
}
};
class Player: public Entity{
private:
string name;
public:
Player(string t_name){
name = t_name;
}
void getName(){
cout << name << endl;
}
};
int main()
{
Entity *e = new Entity();
Player *p = new Player("蔡旭村");
p->getName(); // 正常,调用了Player重写的getName
e->getName(); // 正常,调用了Entity的getName
Entity *ep = p;
// 出现异常,这里e指向p,p是Player,但是调用了Entity的getName(因为e指针是Entity的指针)
ep->getName();
// 这里我希望他调用到正确的函数(Player的getName(),需要使用虚函数)
return 0;
}
Entity指针指向它的派生类Player的指针。此时调用成员方法调用的是Entity的,但是我们这里需要调用的是Player的成员方法。需要用到虚函数,程序修改后如下:
(注意 override 是C++ 11后才有的,可以不写)
#include <iostream>
using namespace std;
class Entity{
public:
virtual void getName(){
cout << "Entity" << endl;
}
};
class Player: public Entity{
private:
string name;
public:
Player(string t_name){
name = t_name;
}
void getName () override{
cout << name << endl;
}
};
int main()
{
Entity *e = new Entity();
Player *p = new Player("蔡旭村");
p->getName(); // 正常,调用了Player重写的getName
e->getName(); // 正常,调用了Entity的getName
Entity *ep = p;
ep->getName(); // 正常,调用了Player重写的getName
return 0;
}
纯虚函数
- 纯虚函数所在的类(接口)不能被实例化,因为这个函数没有定义。
- 纯虚函数没有定义,函数交给派生类去定义。
- 派生类必须实现基类中的纯虚函数。
virtual xxx funName(xxx) = 0; // 纯虚函数
Talk is cheap. Show me the code.
#include <iostream>
using namespace std;
class Api{
public:
virtual string getClassName() = 0; // 纯虚函数
};
class Logs: public Api{
string getClassName() override{
return "Logs";
}
};
class Player: public Api{
string getClassName() override{
return "Player";
}
};
void printClassName(Api *p_api){
cout << p_api->getClassName() << endl;
}
int main()
{
Logs *console = new Logs();
Player player;
printClassName(console);
printClassName(&player);
return 0;
}
代码中 Api
类中有一个获取类名的纯虚函数。 Logs
和 Player
类都继承了 Api
类。
所以 Logs
和 Player
必须实现获取类名的功能。
引入原因
1、为了方便使用多态特性,我们常常需要在基类中定义虚函数。
2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎,孔雀等子类,但动物本身生成对象明显不合常理。