目录
一、虚函数
二. virtual关键词
三.纯虚函数
四.析构函数一定是虚的
一、虚函数
class Person
{
public:
string name;
Person(string n): name(n){}
void print()
{
cout << "Name: " << name << endl;
}
};
class Student: public Person
{
public:
string id;
Student(string n, string i): Person(n), id(i){}
void print()
{
cout << "Name: " << name;
cout << ". ID: " << id << endl;
}
};
//子类指针可以隐含转换为父类指针
//但通过基类对象名,指针,只能访问从基类继承的对象
Person * p = new Student();//创建一个子类对象,赋给父类指针p。
p->print(); // call Person::print()?
#include
#include
using namespace std;
class Person
{
public:
string name;
Person(string n): name(n){}//对name赋值
virtual void print()
{
cout << "Name: " << name << endl;
}
};
class Person2
{
public:
string name;
Person2(string n): name(n){}
virtual void print() = 0; //纯虚函数
};
class Student: public Person
{
public:
string id;//增加了学生的学号。
Student(string n, string i): Person(n), id(i){}
void print()
{
cout << "Name: " << name;
cout << ". ID: " << id << endl;
}
};
void printObjectInfo(Person & p)//可接受person对象,也可接受person的子类对象。让函数有更好的通用性。
{
p.print();//这里面只调用父类的函数。设计函数的初衷就不成立了。如果它去调子类函数的话,万一传进来是父类的函数。那就没有这个函数了。
// 在父类里面加virtual可以改变
}
int main()
{
{
Student stu("yu", "2019");
printObjectInfo(stu);
}
{
Person * p = new Student("xue", "2020");
p->print(); //if print() is not a virtual function, different output
delete p; //if its destructor is not virtual
}
// { //if you want to call a function in the base class
// Student stu("li", "2021");
// stu.Person::print();
// Person * p = new Student("xue", "2020");
// p->Person::print();
// delete p;
// }
return 0;
}
调用的都是父类的函数。
加虚函数结果
二. virtual关键词
常规函数都是静态绑定。编译器在编译源代码的时候。他就决定了在这个位置应该执行哪个函数。
动态的绑定,他并不去决定你到底应该去执行哪个函数。在运行的时候,它根据传进来的参数判断你是什么样的函数。你应该去执行哪个函数?
父类加了虚函数,那么子类也是虚函数。不用所有的都加。
三.纯虚函数
virtual void print() = 0
虚函数是有定义的,纯虚函数是没有定义,这个函数只是一个接口。
这个类就是个纯虚类,就不能创建对象。 调用纯虚函数又不知道他干什么。一般是给父类当继承用的。
四.析构函数一定是虚的
如果不是虚函数,下面这段代码就会出问题。
Person * p = new Student("xue", "2020");
p->print(); 不是虚函数就调父类的,是虚函数就调子类的。
...
...
delete p; //if its destructor is not virtual
如果不是虚函数,就会调用父类的析构函数。



