虚函数引入一种要动态分配的东西,一般通过虚表(vtable)实现编译。虚表就是一个包含类中所有虚函数映射的列表,通过虚表可以在运行时找到正确的被重写的函数。
//demo.cpp
#include<string>
#include <iostream>
class People
{
public:
void GetName()
{
std::cout<<"people"<<std::endl;
}
};
class Student:public People
{
public:
void GetName()
{
std::cout<<"student"<<std::endl;
}
};
int main()
{
People p;
p.GetName();
Student s;
s.GetName();
People *point = new Student();
point->GetName();
}
//打印结果
people
student
people
为什么一个指向派生类的指针调用的是基类的函数呢?
因为在类中正常声明的函数或方法,当调用这个方法的时候,总会去调用属于这个类型的方法。
使用虚函数
//demo.cpp
#include<string>
#include <iostream>
class People
{
public:
virtual void GetName()
{
std::cout<<"people"<<std::endl;
}
};
class Student:public People
{
public:
void GetName()override
{
std::cout<<"student"<<std::endl;
}
};
int main()
{
People p;
p.GetName();
Student s;
s.GetName();
People *point = new Student();
point->GetName();
}
//打印结果
people
student
student
virtual 和 override 关键字
基类中想要声明为虚函数的,要在前面加vitual,派生类中,重写的虚函数要在函数后加override关键字,override可以省略,建议添加有助于阅读。
c++接口 特殊的虚函数–纯虚函数
纯虚函数允许在基类中定义一个没有实现的函数,强制在基类中进行实现。
//demo.cpp
#include<string>
#include <iostream>
class People
{
public:
virtual void GetName()=0;//纯虚函数
};
class Student:public People
{
public:
void GetName()override
{
std::cout<<"student"<<std::endl;
}
};
int main()
{
//People p;
//p.GetName();
Student s;
s.GetName();
People *point = new Student();
point->GetName();
}
//打印结果
student
student
People类只有一个纯虚函数,可以将People类称为接口类,接口类不能实例化对象。派生类Student必须实现基类中的纯虚函数,否则也不能实例化对象。