首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++中虚拟公共类的副作用

在C++中,虚拟公共类的副作用是指在继承关系中,当一个类继承自一个虚拟公共类时,会导致派生类对象的大小增加,并且可能引发一些不可预测的行为。

虚拟公共类是指在基类中使用虚拟继承关键字"virtual"来声明的公共类。它的作用是解决多重继承中的菱形继承问题,即一个派生类同时继承自两个或多个具有公共基类的类。通过使用虚拟继承,可以确保只有一个基类子对象被派生类共享,从而避免了派生类中出现多个基类子对象的问题。

然而,虚拟公共类的副作用是会增加派生类对象的大小。这是因为派生类需要额外存储一个指向虚拟基类子对象的指针,用于访问虚拟基类的成员。这个指针的大小取决于编译器的实现,通常是一个指针大小(4字节或8字节)。因此,虚拟公共类会增加派生类对象的内存消耗。

另外,虚拟公共类的副作用还包括可能引发一些不可预测的行为。由于虚拟公共类的构造函数和析构函数会在派生类的构造函数和析构函数中被调用,因此在派生类的构造函数和析构函数中对虚拟公共类的成员进行操作可能会导致一些意想不到的结果。这是因为在派生类的构造函数中,虚拟公共类的成员可能还没有被完全构造,而在析构函数中,虚拟公共类的成员可能已经被析构。因此,在使用虚拟公共类时需要特别小心,避免在构造函数和析构函数中对虚拟公共类的成员进行复杂的操作。

总结起来,虚拟公共类在解决多重继承中的问题方面具有优势,但也带来了一些副作用,包括增加派生类对象的大小和可能引发不可预测的行为。在使用虚拟公共类时,需要注意这些副作用,并谨慎处理相关的操作。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++核心准则​讨论:将基析构函数设为公共虚拟,或受保护和非虚拟

也就是说,是否应该允许通过指向基指针进行销毁?如果是,则base析构函数必须是公共才能被调用,否则虚拟调用它会导致未定义行为。...否则,应该对其进行保护,以便只有派生才能在自己析构函数调用它,这个析构函数也应该是非虚,因为它不需要虚拟地运行。...这种情况导致较早编码标准对所有基析构函数都必须是虚拟提出了全面的要求。这太过分了(即使是常见情况);相反,规则应该是当且仅当基析构函数是公共时,才将它们虚函数化。...如第39项所述,对于普通成员函数,选择之间是允许以非虚拟方式(通过指向Base指针)调用它(但如果它调用虚拟函数(例如在NVI或模板方法模式),则可能具有虚拟行为) ),实际上还是根本没有。...因此,如果可以调用(即是公共)基析构函数,则它是虚拟,否则是非虚拟

1.1K20

C++

对于,接口是用户调用程序,交互系统就是对象,而接口是编写的人提供方法,接口让程序员能够编写与对象交互代码,从而让程序能够使用对象,比如要计算string对象字符,可以用方法size...,也是接口,如果要使用,必须了解其公共接口,如果要编写,必须创建其公共接口。... 通常C++程序员把接口(定义)放在头文件当中,并将实现方法(方法)放在程序源代码当中。...这里要说明默认权限是private 实现成员函数 成员函数特征: 定义成员函数 使用::作用域解析运算符标明所属 方法可以访问private成员 比如我要访问上面update函数 void...使用 C++目标是使得和基本类型尽可能相同,我们声明和定义都已经编写完成,下面我们通过文件来使用这些接口测试一下: 这里还需要说明一下C++文件结构,以及这里我们使用到了之前在C语言预编译处理说到内容

19010
  • C++虚拟继承与虚基

    1.多重继承带来问题 C++虚拟继承一般发生在多重继承情况下。C++允许一个有多个父,这样就形成多重继承。...(1)当在多条继承路径上有一个公共,在这些路径某几条汇合处,这个公共就会产生多个实例(或多个副本),若只想保存这个基一个实例,可以将这个公共说明为虚基,就像Student和Employee...(2)被虚拟继承,叫做虚基。虚基实际指的是继承方式,而非一个基,是动词,而非名词。 (3)为了实现虚拟继承,派生对象大小会增加4。...(4)虚拟继承,虚基对象是由最远派生构造函数通过调用虚基构造函数进行初始化,派生构造函数成员初始化列表必须列出对虚基构造函数调用;如果未列出,则表示使用该虚基缺省构造函数。...因为虚拟继承只是表名某个基对象在派生对象只被构造一次,而在本例Student和Employee对象在EGStudent对象本来就不会被构造多次,所以不将它们申明虚基也是完全可以

    90220

    C++封装

    前言 昨天分享了面向对象里面的和对象基本概念,今天我们继续来分享c++里面的里面的其它用法。(每天积累一点点,日积月累你也是专家!)。...封装 1、在C++,当我们使用时候,我们首先要注意实现细节和使用方式(也就是说我们在做任何事情前,先要考虑好事情大局观甚至加一些要注意细节问题,不然一拿到一件事情,没有方向性去做事情...最后我们要注意是,必须在表示法定义属性和行为公开级别(类似于文件系统中文件权限)。 3、C++封装: ——成员变量:C++中用于表示属性变量。...——成员函数:C++中用于表示行为函数。 ——C++可以给成员变量和成员函数定义定义访问级别: public: 表示成员变量和成员函数可以在内部和外部访问和调用。...注意一点:在C++中使用strcut定义所有成员(成员变量和成员函数)默认为pubic(公有的,外部可以调用和访问)。

    66530

    C++C++ this 指针用法 ① ( C++ this 指针引入 | this 指针用法 | 代码示例 )

    一、C++ this 指针 1、C++ this 指针引入 在 C++ , this 指针 是一个特殊指针 , 由系统自动生成 , 不需要手动声明定义 , 在每个 非静态成员函数..., 因此 this 指针是内部使用指针 , 使用 this 可以访问 实例对象 所有 公有 public / 保护 protected / 私有 private 成员 ; 2、C++ ...this 指针用法 C++ this 指针用法 : 使用 this 作为指针 : 在 非静态成员函数 , 直接使用 this 作为 本实例对象 指针 ; this 使用 this-> 访问成员变量...访问成员变量 : 在 非静态成员函数 , 直接使用如下语法 , 访问 本实例对象 非静态成员变量 ; 先获取指针指向数据 然后访问数据成员变量 ; (*this).成员变量名 在 C++... , 定义了 成员变量 age 和 height , 在 构造函数 中进行初始化 , 可以使用 this-> age 访问 age 成员变量 , 使用 this->height 访问 height

    31420

    C++ 容器详解

    大家好,又见面了,我是你们朋友全栈君 C++容器包括“顺序存储结构”和“关联存储结构”,前者包括vector,list,deque等;后者包括set,map,multiset,multimap...若需要存储元素数在编译器间就可以确定,可以使用数组来存储,否则,就需要用到容器了。...6、用vector存储自定义对象时,自定义对象须满足: a、有可供调用无参构造函数(默认或自定义); b、有可用拷贝赋值函数(默认或自定义) 7、迭代器iterator...value_type 容器存放元素类型 reference 容器存放元素类型引用 const_reference 容器存放元素类型常量引用,这种引用只能读取容器元素和进行const操作...引用相同容器两个迭代器相减结果类型(list和关联容器没有定义operator-) size_type 用于计算容器项目数和检索顺序容器类型(不能对list检索) 8.序列容器 (1)vector

    79320

    C++ std::string

    C++ 在其定义中有一种将字符序列表示为 class 对象方法。这个叫做 std::string。String 将字符存储为具有允许访问单字节字符功能字节序列。 ...std:: 字符串与字符数组 字符数组只是一个可以由空字符终止字符数组。字符串是定义表示为字符流对象 字符数组大小必须静态分配,如果需要,不能在运行时分配更多内存。...字符串操作 输入函数 1. getline()  :- 该函数用于在对象内存存储用户输入字符流。 2. push_back()  :- 该函数用于在字符串末尾 输入一个字符。...3. pop_back()  :- 从 C++11 引入(用于字符串),该函数用于删除字符串最后一个字符。...它需要 3 个参数,目标字符数组,要复制长度和开始复制字符串起始位置。 13. swap()  :- 该函数将一个字符串与另一个字符串交换**。

    1.1K20

    C++和对象(

    ---- 前言 祖师爷在设计 C++ 时,规定每个中都有六个默认成员函数,即使我们不主动写,编译器也会自动生成,这些成员函数就是神秘天选之子,不仅神秘,而且还很强大,可以这么说:和对象是否学懂...注意:数据类型主要分为两 简言之:默认构造函数有点像不干实事函数 假设我们只有内置类型,那么默认构造函数真就什么都没有做;出现自定义类型时,也只会主动去调用它默认构造函数...,至于自定义类型默认构造函数干了什么,默认构造函数是不管 因祖师爷设计疏忽而留下坑,为后世学习C++增加了阻力 这么看来,这个天选之子似乎没有什么用,默认构造函数还得我们自己编写 不过在有些场景下...,默认构造函数很有用 题目:用栈实现队列 需要在队列这个,调用两个栈,实现队列 此时我们只需要写好栈默认构造函数 队列默认构造函数不需要写,因为自动生成会去调用自定义类型默认构造函数,...+中新关键字,operator 作用很简单,实现自定义类型运算 使用规则: operator 函数操作数取决于参数个数 operator 一般写在,方便通过 this 指针访问成员变量 写在

    22510

    c++】string---标准库(STL)string

    STL是C++优秀作品,有了它陪伴,许多底层数据结构以及算法都不需要自己重新造轮子,站在前人肩膀上,健步如飞快速开发 1.5 如何学习STL ​ 简单总结一下 :学习 STL 三个境界:...string,很少有人去使用C库字符串操作函数 3....标准库string 3.1 string(了解) string文档介绍:https://cplusplus.com/reference/string/string/?...,因为还有其他对象在使用该资源 4.4 string模拟实现代码 根据cplusplus网站对string介绍,我们可以手动实现相关操作函数 string - C++ Reference (cplusplus.com...) 作为一名c++研发工程师,我们要对底层有更深理解,学习大佬写法,参考大佬思维,这对我们以后学习和工作是有很大帮助 1 代码内容和测试函数 这是.h文件内容 #pragma once /

    18710

    A是公共,应在名为A.java文件声明错误

    A是公共,应在名为A.java文件声明”这句话需要分两步来理解: 1、如果类A被声明为公共(public),那么必须将A保存在名为A.java文件; 2、反之,在一个文件中最多包含一个顶级公共...,并且该公共名字与文件名相同。...比如文件A.java,允许定义一个或多个,但最多允许一个顶级公共,此类名为A。此处强调顶级意思是,允许非顶级公共存在,如内部公共等。...第二种 这是你命名错误 把文件名改为 A.java 因为你里面的是 public class A{} 要不你把你这个公共(public)去掉 要不就要和名保持一致 第三种 一个文件中最多只能有一个是...如果已经有了这个公共 那么这个文件名必须和名相同!

    2.4K50

    C++和对象()

    如果一个什么成员都没有,简称为空。空什么都没有吗?并不是的,任何一个在我们不写情况下,都会自动生成下面 6个默认成员函数。 在这个地方,对于这6个默认成员函数,前面四个是比较重要。...:声明了d3函数,该函数无参,返回一个日期类型对象 //Date d3(); } int main() { TestDate(); return 0; } 如果类没有显式定义构造函数,则C...但是如果写在全局,又引发了另一个问题: 如何去访问私有属性❓ 1.直接把私有权限改为公共权限 2.在设置get和set方法,然后在外直接调用即可 3.友元声明 同时,全局变量/全局函数在所有文件...,实际修饰该成员函数隐含this指针,表明在该成员函数不能对任何成员进行修改。...至此,内容比较多了,我们先到这里结束掉我们和对象()内容

    1.2K30

    C++】————和对象(

    如果一个什么成员都没有,简称为空。空什么都没有吗?...如果类没有显式定义构造函数,则 C++ 编译器会自动生成一个无参默认构造函数,一旦用户显式定义编译器将不再生成。...private: int _year; int _month; int _day; }; int main() { Date d1; Date d2(2022, 3, 3); } 在日起析构函数似乎没什么用处...,但在栈析构函数却有着十分重要作用 class stack { public: stack(int capcity = 4) //将上面的合而为一 { if (capcity ==...二、赋值运算符重载 2.1运算符重载: 在C++,为了增加代码可读性增加了运算符重载,运算符重载是具有特殊函数名函数,也具有返回值类型,函数名字以及参数序列,其返回值与参数列表与普通函数类似

    10810

    C++和对象(

    构造函数本质是要替代我们以前Stack和DateInit函数功能,构造函数⾃动调⽤特点就完美的替代了Init。 构造函数特点: 1. 函数名与名相同。...如果类没有显式定义构造函数,则C++编译器会⾃动⽣成⼀个⽆参默认构造函数,⼀旦⽤⼾显式定义编译器将不再⽣成。 6....赋值运算符重载 5.1运算符重载 • 当运算符被⽤于类型对象时,C++语⾔允许我们通过运算符重载形式指定新含义。...C++规定类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应运算符重载,则会编译报错。...• const实际修饰该成员函数隐含this指针,表明在该成员函数不能对任何成员进⾏修改。

    6910

    c++长度解析

    通常我们定义一个,它所占空间有多大呢?...func2(void){ printf("heihei\n"); }; public: char number; int number1; }; 我们输出这两个长度...至于为什么第二个是8,就是内存对齐问题了,可以参考之前内存申请帖子。   我们发现,一个长度是它变量所占用空间,也就是说函数是不占用空间。...这是因为一个变量时属于对象,而一个函数是属于这个。   那么因对象不同而不同虚函数又会怎样呢?   ...因此有虚函数,会多出一个指针空间。但仅仅分配一个指针。比如第一个函数会用vptr[1]来表示,第二个用vptr[2]来表示,而索引0是表信息。   如有不对地方,还请多多指正。

    79950

    C++和对象(

    日期实现 7. const成员 8. 取地址及const取地址操作符重载 ---- 1. 6个默认成员函数 如果一个什么成员都没有,简称为空真的什么都没有吗?...// 无参不要像下面这样写 Date d4(); Date func(); 重点: 5.如果类没有显式定义构造函数,则C++编译器会自动生成一个无参默认构造函数,一旦用户显式定义编译器将不再生成。...注意:C++11 针对内置类型成员不初始化缺陷,又打了补丁,即:内置类型成员变量在 声明时可以给默认值。...; } 从调试来看,会进入Time,调用Time拷贝构造函数:  有个要补充点,就是形参最好加上const!...①在创建返回月天数函数时候,不能将数组创建在函数外,

    1.2K20
    领券