用来修饰父类中的函数:
1、修饰父类中的普通函数:
1 #include <iostream> 2 #include <string> 3 #include <stdlib.h> 4 5 using namespace std; 6 7 class base 8 { 9 public: 10 void fun1(){ cout << "this is base::fun1" << endl;} 11 virtual void fun2(){ cout << "this is base::fun2" << endl;} 12 }; 13 14 class base1:public base 15 { 16 public: 17 void fun1(){ cout << "this is base1::fun1" << endl;} 18 void fun2(){ cout << "this is base1::fun2" << endl;} 19 }; 20 21 int main(int argc, char *argv[]) 22 { 23 if (argc); 24 if (argv); 25 26 base *p = new base1(); 27 28 p->fun1(); 29 p->fun2(); 30 31 return 0; 32 }
输出:
this is base::fun1 this is base1::fun2
使用virtual修饰的函数会根据实际对象的类型来调用,没有使用virtual修饰的根据指针的类型来调用。关键的特点是“动态联编”,可以在运行时判断指针的指向的对象,并自动调用相关的函数。
2、修饰父类中的析构函数:
1 #include <iostream> 2 #include <string> 3 #include <stdlib.h> 4 5 using namespace std; 6 7 class grandfather 8 { 9 public: 10 grandfather (){ cout << "this is grandfather::construct" << endl;} 11 ~grandfather(){ cout << "this is grandfather::destruct" << endl;} 12 }; 13 14 class father: public grandfather 15 { 16 public: 17 father (){ cout << "this is father::construct" << endl;} 18 ~father(){ cout << "this is father::destruct" << endl;} 19 }; 20 21 class son: public father 22 { 23 public: 24 son (){ cout << "this is son::construct" << endl;} 25 ~son(){ cout << "this is son::destruct" << endl;} 26 }; 27 28 int main(int argc, char *argv[]) 29 { 30 if (argc); 31 if (argv); 32 33 father *p = new son(); 34 35 delete p; 36 37 return 0; 38 }
output:
this is grandfather::construct this is father::construct this is son::construct this is father::destruct this is grandfather::destruct
由此我们发现,这样操作没有析构掉son的内容,存在危险,
当father或者grandfather中的任一析构函数加上关键字virtual,
输出变为:
1 this is grandfather::construct 2 this is father::construct 3 this is son::construct 4 this is son::destruct 5 this is father::destruct 6 this is grandfather::destruct
符合预期
3、纯虚函数
在虚函数的后面加了一个=0;定义了纯虚函数的类是一个抽象类。
virtual void func() = 0;
注意:
- 定义了纯虚函数的类不能实例化,即不能创建对象;
- 继承了含有虚函数的父类的子类没有实现纯虚函数也不能够实例化;
4、修饰继承性
若一个类继承的两个类或者多个类有公共的基类时:
1 #include <iostream> 2 #include <string> 3 #include <stdlib.h> 4 5 using namespace std; 6 7 class grandfather 8 { 9 public: 10 grandfather (){ cout << "this is grandfather::construct" << endl;} 11 ~grandfather(){ cout << "this is grandfather::destruct" << endl;} 12 }; 13 class father1: public grandfather 14 { 15 public: 16 father1 (){ cout << "this is father1::construct" << endl;} 17 virtual ~father1(){ cout << "this is father1::destruct" << endl;} 18 }; 19 class father2: public grandfather 20 { 21 public: 22 father2 (){ cout << "this is father2::construct" << endl;} 23 virtual ~father2(){ cout << "this is father2::destruct" << endl;} 24 }; 25 class son: public father1, father2 26 { 27 public: 28 son (){ cout << "this is son::construct" << endl;} 29 ~son(){ cout << "this is son::destruct" << endl;} 30 }; 31 32 int main(int argc, char *argv[]) 33 { 34 if (argc); 35 if (argv); 36 father1 *p = new son(); 37 delete p; 38 return 0; 39 }
输出:
this is grandfather::construct this is father1::construct this is grandfather::construct this is father2::construct this is son::construct this is son::destruct this is father2::destruct this is grandfather::destruct this is father1::destruct this is grandfather::destruct
出现了两次的grandfather的构造和析构,不符合预期;
所以在father1/2继承grandfather时需要加上virtual关键字
class father1: virtual public grandfather { public: father1 (){ cout << "this is father1::construct" << endl;} virtual ~father1(){ cout << "this is father1::destruct" << endl;} }; class father2: virtual public grandfather { public: father2 (){ cout << "this is father2::construct" << endl;} virtual ~father2(){ cout << "this is father2::destruct" << endl;} };
输出变为:
this is grandfather::construct this is father1::construct this is father2::construct this is son::construct this is son::destruct this is father2::destruct this is father1::destruct this is grandfather::destruct
比较符合我们的预期
标签:son,virtual,C++,destruct,grandfather,关键字,construct,include From: https://www.cnblogs.com/xuekui-jin/p/17692238.html