草庐IT

virtual-inheritance

全部标签

c++ - 虚函数和多重继承情况下的对象布局

我最近在接受采访时被问及有关具有虚函数和多重继承的对象布局。我在上下文中解释了它是如何在不涉及多重继承的情况下实现的(即编译器如何生成虚拟表,在每个对象中插入一个指向虚拟表的secret指针等等)。在我看来,我的解释似乎缺少了一些东西。所以这里有问题(见下面的例子)C类对象的确切内存布局是什么。C类的虚拟表条目。A、B和C类对象的大小(由sizeof返回)。(8、8、16??)如果使用虚继承呢?大小和虚拟表条目肯定会受到影响吗?示例代码:classA{public:virtualintfunA();private:inta;};classB{public:virtualintfunB(

c++ - 当 `virtual` 是一个相当大的开销时,是否有任何经验法则?

我的问题基本上完全在标题中陈述,但是让我详细说明。问题:也许值得重新措辞,virtual多么复杂/简单方法必须是,使机制产生相当大的开销?这有什么经验法则吗?例如。如果需要10分钟,使用I/O,复杂if语句、内存操作等,这不是问题。或者,如果您写virtualget_r(){returnsqrt(x*x+y*y);};并在循环中调用它,您会遇到麻烦。我希望这个问题不是太笼统,因为我寻求一些笼统但具体的技术答案。要么很难/不可能说出来,要么虚拟调用占用了太多的时间/周期资源,而数学需要这个,I/O这个。也许一些技术人员知道一些通用数字进行比较或进行一些分析并可以分享一般结论。尴尬的是我不

c++ - "Missing non-virtual thunks"和继承顺序

我们在C++中有一个大型代码库,在进行了一些小的重构(添加了一个类并重写了一些相关方法)之后,我们开始在GCC3和4上遇到链接器错误。链接器错误特别是“缺少对非虚拟的引用”thunks”在我们的大型SDK中子类化的小示例程序中。除了一些似乎已解决的旧GCC错误外,在网上搜索并没有给出很多提示。问题的属性好像是:GCC3.4.6&4.3.3使用-O2优化多重继承,包括偶尔的虚拟继承。改变继承顺序,比如说,Foo类:公共(public)A,公共(public)B{}到Foo类:公共(public)B,公共(public)A{}在缺少thunk的类上“修复”了问题。虚继承只出现在一个单一的、

c++ - 有没有办法在 C++ 基类中创建 "virtual"变量?

我有一个带有指针的基类,需要在所有子类的构造函数中专门对其进行初始化。我怎样才能确保这个变量在子类的构造函数中被初始化?我基本上想要与制作纯虚函数相同的功能,除了指向对象的指针。有办法吗?我的代码看起来像这样:A.hpp:classA{protected:A();X*pointer;};B.hpp:classB:publicA{public:B();};B.cpp:B::B():A(){//howdoimakesurepointergetsinitializedhere?}有什么办法可以实现吗? 最佳答案 改rebase类的构造函数

C++:莫名其妙的 "pure virtual function call"错误

我在使用MicrosoftVisualC++2015时遇到了一些困难,但能够用一个小程序重现该问题。给定以下类:classBaseClass{public:BaseClass():mValue(0),mDirty(true){}virtual~BaseClass(){}virtualintgetValue()const{if(mDirty)updateValue();returnmValue;}protected:virtualvoidupdateValue()const=0;mutableboolmDirty;mutableintmValue;};classDerivedClass:

c++ - 有没有办法不继承子类中函数的 "virtualness"?

在C++中是否可以让一个类覆盖一个虚函数,但只有在通过父类(superclass)调用该函数时才具有虚拟分派(dispatch)(即,当它被静态类型为子类的东西调用时不存在)?我知道这不会发生,但有什么方法可以接近吗?想要这样做的原因是我有两个类都公开了一个flush()函数。在我的程序中的绝大多数时间,我直接在我知道类型的子类对象上调用flush(),因此我不需要虚拟分派(dispatch)。但是我想在混合中添加一个父类(superclass),这样我就可以很少将对任一类的实例的引用传递给doSomethingThenFlush()函数,该函数将调用flush()实际上。我知道我可以

c++ - 将基类函数标记为 virtual 和 final 有什么意义吗?

这个问题在这里已经有了答案:What'sthepointofafinalvirtualfunction?(11个答案)关闭5年前。在variousexplanationsC++11的final关键字,我看到了这样的例子。classbase{public:virtualvoidf()final;};classderived:publicbase{public:virtualvoidf();//Illegalduetobase::f()declaredfinal.};这实际上是final的有用用法吗?为什么要在基类中声明一个虚函数(暗示它可以在派生类中有用地重写)然后立即将其标记为fina

c++ - 为什么我们不能在 COM 中使用 "virtual inheritance"?

我读过一些模糊的声明virtualinheritance没有提供COM需要的内存结构,所以我们只好使用普通的继承。发明虚拟继承是为了解决菱形继承(钻石问题)。有人可以向我展示这两种继承方法之间内存结构细节差异的图示吗?以及虚拟继承不适合COM的关键原因。最好有照片。非常感谢。 最佳答案 首先,在COM中总是使用虚拟继承的行为。QueryInterface无法返回不同的值,例如IUnknown基指针取决于用于获取它的派生类。但是您是对的,这与C++中的虚拟继承机制不同。C++不使用QueryInterface函数进行向上转换,因此它需

c++ - 用于多个虚拟继承和类型转换的虚拟表和虚拟指针

我对vptr和内存中对象的表示不太困惑,希望您能帮助我更好地理解问题。考虑到B继承自A,并且都定义了虚函数f()。从我学到的知识,B类对象在内存中的表示形式如下:[vptr|A|B]以及vtbl指向的vptr包含B::f()。我还理解,将对象从B转换为A除了忽略对象末尾的B部分外,什么都没有做。是真的吗这不是错误的行为吗?我们希望A类型的对象执行A::f()方法,而不是B::f()。系统中是否存在与类数相同的vtables?从两个或多个类继承的类的vtable看起来如何?C的对象将如何在内存中表示?与问题3相同,但具有虚拟继承。 最佳答案

c++ - 异常是否需要虚拟继承?

我理解在使用多重继承时需要虚拟继承——它解决了可怕的菱形继承(钻石问题)。但是如果我不使用多重继承呢?是否需要虚拟继承?我似乎记得听说它对异常很重要(抛出派生类,通过基类引用捕获)。但是,虚拟析构函数是否足以满足此要求?我已经尝试搜索我曾经在这方面看到的引用页面,但我似乎找不到它。 最佳答案 您可能正在考虑这个Boost.Exceptionguideline,为了完整起见,我将在此处复制:在异常类型中使用虚拟继承异常类型在从其他异常类型派生时应该使用虚拟继承。这一见解归功于AndrewKoenig。使用虚拟继承可以防止异常处理程序中