首页 > 编程语言 >C++ virtual关键字

C++ virtual关键字

时间:2023-09-10 23:11:20浏览次数:48  
标签:son virtual C++ destruct grandfather 关键字 construct include

用来修饰父类中的函数:

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

相关文章

  • 18、复合类型之指针(P47、P48、P49、P50);C++ primer 2.3.2
    1、C++中的“声明符”是什么?声明符是用来指定变量或函数的类型、名称和属性的符号。例如:intlist[20]; 声明了一个名为list的整型数组,它有20个元素。int是类型说明符,list[20]是声明符char*cp; 声明了一个名为cp的指向字符的指针1。*cp是声明符doublefunc(void);......
  • c++中的数论知识
    写在开头:word的公式打不上来,只能截图了一.组合数学(1)加法定理与乘法原理加法原理:做一件事情,完成它可以有n类办法,在第一类办法中有m1种不同的方法,在第二类办法中有m2种不同的方法,……,在第n类办法中有mn种不同的方法。那么完成这件事共有N=m1+m2+…+mn种不同的方法。乘法原理:做一......
  • C++的运算符重载介绍
    所谓重载,就是赋予新的含义。函数重载(FunctionOverloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(OperatorOverloading)也是一个道理,同一个运算符可以有不同的功能。实际上,我们已经在不知不觉中使用了运算符重载。例如,+号可以对不同类型(int、float等)的......
  • C++的知识
    首先,让我们了解一下C++是什么。C++是一种高级的面向对象编程语言,泰兰德幻,它是C语言的扩展。由于其高度的灵活性和强大的功能,C++在各种领域中得到了广泛的应用,尤其在游戏开发、系统编程和嵌入式设备等方面。C++的优势之一是其强大的数据类型系统。C++支持不同的数据类型,包括整数、......
  • C++ 算法竞赛、03 周赛篇 | AcWing 第4场周赛
    AcWing第4场周赛竞赛-AcWing3694A还是B3694.A还是B-AcWing题库简单题#include<algorithm>#include<cstring>#include<iostream>usingnamespacestd;intn;inta,b;intmain(){cin.tie(0);charc;cin>>n;for(int......
  • cpp: vscode 配置C,C++
    下载编译器MinGW并解压官网页面:https://www.mingw-w64.org/下载页面:https://sourceforge.net/projects/mingw-w64/files/https://cmake.org/download/需要环境变量进行设置task.json:{"tasks":[{"type":"cppbuild",&quo......
  • C++编程语言在线学习系统-计算机毕业设计源码+LW文档
    摘要随着互联网技术的推进,我国高等教育逐渐实现信息化。许多精品C++编程语言在线学习系统的开发建设大大提高了教职工的教学效率,也为培养更多的高素质人才提供了途径。但是C++编程语言在线学习系统的发展也存在交互性不强、资源更新缓慢、教学形式单一等问题。因此,笔者设想开发一......
  • Java基础——变量和关键字
    变量java编程中分为变量和常量,常量是指值不能改变的量,如1,“HelloWorld”等。变量意为变化的量。可以看作是用于存放数据的一个容器。一个代词,指代它里面的那个数。如,inta=0;现在变量a的值为0,我们可以让a的值为1,a=1;通过这种赋值变量a的值变为了1。变量的定义变量类型标识符;......
  • Excelopenpyxl 关键字调用封装
    importopenpyxl,osfromPythonUI自动化.keywords_关键字驱动.综合.commonimportWebUIKeys,logfromopenpyxl.stylesimportFont,PatternFill#log=Logs().logger()classexcelOption():#获取Excel文件def__init__(self,file_path=None):if......
  • C++中的typeid运算符
    typeid运算符用来获取一个表达式的类型信息。类型信息对于编程语言非常重要,它描述了数据的各种属性:对于基本类型(int、float等C++内置类型)的数据,类型信息所包含的内容比较简单,主要是指数据的类型。对于类类型的数据(也就是对象),类型信息是指对象所属的类、所包含的成员、所在的继承......