我想知道" 虚拟基类 "是什么以及它意味着什么.
让我举个例子:
class Foo
{
public:
void DoSomething() { /* ... */ }
};
class Bar : public virtual Foo
{
public:
void DoSpecific() { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud) class A { public: void eat(){ cout<<"A";} };
class B: virtual public A { public: void eat(){ cout<<"B";} };
class C: virtual public A { public: void eat(){ cout<<"C";} };
class D: public B,C { public: void eat(){ cout<<"D";} };
int main(){
A *a = new D();
a->eat();
}
Run Code Online (Sandbox Code Playgroud)
我理解钻石问题,上面的代码没有那个问题.
虚拟继承究竟是如何解决问题的?
我的理解:
当我说A *a = new D();,编译器想要知道类型的对象是否D可以分配给类型的指针A,但它有两个可以遵循的路径,但不能自己决定.
那么,虚拟继承如何解决问题(帮助编译器做出决定)?
c++ inheritance multiple-inheritance virtual-inheritance diamond-problem
我不明白为什么在下面的代码中,当我实例化一个类型的对象时daughter,默认的grandmother()构造函数被调用?
我认为grandmother(int)应该调用构造函数(遵循我的mother类构造函数的规范),或者由于虚拟继承,这个代码根本不应该编译.
这里编译器grandmother在我的后面静默调用默认构造函数,而我从来没有要求它.
#include <iostream>
class grandmother {
public:
grandmother() {
std::cout << "grandmother (default)" << std::endl;
}
grandmother(int attr) {
std::cout << "grandmother: " << attr << std::endl;
}
};
class mother: virtual public grandmother {
public:
mother(int attr) : grandmother(attr) {
std::cout << "mother: " << attr << std::endl;
}
};
class daughter: virtual public mother {
public:
daughter(int attr) : mother(attr) {
std::cout << "daughter: " << …Run Code Online (Sandbox Code Playgroud) 我有三个班:
class A {};
class B : virtual public A {};
class C : virtual public A {};
class D: public B, public C {};
Run Code Online (Sandbox Code Playgroud)
尝试从A*到B*的静态强制转换我得到以下错误:
cannot convert from base A to derived type B via virtual base A
Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个实现许多接口的相当大的对象.其中一些接口是纯虚拟的.我可能在钻石继承方面遇到问题.Visual Studio正在报告警告C4250 ('class1' : inherits 'class2::member' via dominance).首先,这些类实际上是应该继承的.以下是导致此问题的部分类设计.
A B C
\ / \ /
\ / \ /
AB BC
| |
| BC2
| |
\ D: Implementation of B, C, BC, BC2
\ /
Big
Run Code Online (Sandbox Code Playgroud)
在整个树中,只有D实现了虚方法,没有其他相关方法的定义.B的所有虚拟方法都列在警告中.如果重要,D是一个完整的类.
我读到这种情况发生在Boost序列化中,忽略警告是安全的.
这种方法我试图实现有效吗?忽视这个警告是否安全?
注1:这不是Visual Studio Compiler警告C4250('class1':通过优势继承'class2 :: member')的重复,我尝试了那里提出的解决方案.
注2:我也可以发送类图,但它比这复杂一点.
编辑: 完整警告如下:
warning C4250: 'gge::resource::ImageResource' : inherits
'gge::graphics::ImageTexture::gge::graphics::ImageTexture::drawin'
via dominance
Run Code Online (Sandbox Code Playgroud)
gge::resource::ImageResource在绘图中是大的,gge::graphics::ImageTexture是D,drawin是我得到警告的六种方法之一.
请考虑以下代码:
struct Base {};
struct Derived : public virtual Base {};
void f()
{
Base* b = new Derived;
Derived* d = static_cast<Derived*>(b);
}
Run Code Online (Sandbox Code Playgroud)
这是标准([n3290: 5.2.9/2])禁止的,因此代码无法编译,因为Derived 实际上是继承自的Base.virtual从继承中删除使代码有效.
这条规则存在的技术原因是什么?
最近遇到了一个对我来说很新的C++链接器错误.
libfoo.so: undefined reference to `VTT for Foo'
libfoo.so: undefined reference to `vtable for Foo'
Run Code Online (Sandbox Code Playgroud)
我认识到这个错误并解决了我的问题,但我还有一个唠叨的问题:什么是VTT?
旁白:对于那些感兴趣的人,当您忘记定义类中声明的第一个虚函数时,会出现问题.vtable进入类的第一个虚函数的编译单元.如果你忘了定义那个函数,你会得到一个链接器错误,它无法找到vtable而不是更加开发人员友好的找不到该函数.
这是代码:
struct Biology
{
Biology() { cout << "Biology CTOR" << endl; }
};
struct Human : Biology
{
Human() { cout << "Human CTOR" << endl; }
};
struct Animal : virtual Biology
{
Animal() { cout << "Animal CTOR" << endl; }
};
struct Centaur : Human, Animal
{
Centaur() { cout << "Centaur CTOR" << endl; }
};
int main()
{
Centaur c;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码打印:
Biology CTOR
Biology CTOR
Human CTOR
Animal CTOR
Centaur CTOR …Run Code Online (Sandbox Code Playgroud) c++ inheritance constructor multiple-inheritance virtual-inheritance
编辑3:请务必在回答之前清楚地了解我的要求(有EDIT2和很多评论).有(或有)许多答案清楚地表明对问题的误解(我知道这也是我的错,对不起)
嗨,我class B: public virtual A {...}在C++中查看了关于虚拟继承()的问题,但没有找到我的问题的答案.
我知道虚拟继承存在一些问题,但我想知道的是虚拟继承被认为是一种好的设计.
我看到人们提到类似IUnknownor的接口ISerializable,而且该iostream设计也基于虚拟继承.那些是很好地利用虚拟继承的好例子,是因为没有更好的选择,或者因为在这种情况下虚拟继承是正确的设计?谢谢.
编辑:澄清,我问的是现实生活中的例子,请不要抽象.我知道虚拟继承是什么以及哪种继承模式需要它,我想知道的是何时它是做事的好方法而不仅仅是复杂继承的结果.
EDIT2:换句话说,我想知道钻石层次结构(这是虚拟继承的原因)何时是一个好的设计
我正在考虑在实时应用程序中使用虚拟继承.使用虚拟继承是否会产生类似于调用虚函数的性能影响?有问题的对象只会在启动时创建,但我担心层次结构中的所有函数是否都将通过vtable调度,或者只是来自虚拟基类的函数.
c++ ×10
inheritance ×3
downcast ×2
static-cast ×2
casting ×1
constructor ×1
gcc ×1
performance ×1
real-time ×1
vtable ×1
vtt ×1