C++ 为什么';虚拟';继承不是默认行为?

C++ 为什么';虚拟';继承不是默认行为?,c++,inheritance,virtual,multiple-inheritance,diamond-problem,C++,Inheritance,Virtual,Multiple Inheritance,Diamond Problem,我理解从基类派生时使用virtual关键字的要求,以避免与菱形继承相关的歧义问题 但是,我的问题是为什么C++中的默认行为不是派生类,不管是否存在钻石问题? 在钻石继承不存在的情况下使用“virtual”关键字有什么“危害”吗?有开销,试试看: #include <iostream> struct Foo { int a; }; struct Bar : Foo { int b; }; struct Baz : virtual Foo { int b;

我理解从基类派生时使用virtual关键字的要求,以避免与菱形继承相关的歧义问题

<>但是,我的问题是为什么C++中的默认行为不是派生类,不管是否存在钻石问题?


在钻石继承不存在的情况下使用“virtual”关键字有什么“危害”吗?

有开销,试试看:

#include <iostream>

struct Foo {
    int a;
};

struct Bar : Foo {
    int b;
};

struct Baz : virtual Foo {
    int b;
};

int main() {
    std::cout << sizeof(Foo) << " ";
    std::cout << sizeof(Bar) << " ";
    std::cout << sizeof(Baz) << "\n";
}
#包括
结构Foo{
INTA;
};
结构栏:Foo{
int b;
};
结构Baz:虚拟Foo{
int b;
};
int main(){

std::cout虚拟继承有一个运行时开销:转换指针需要一个只有在运行时才知道的调整,而对于非虚拟继承,它可以在编译时知道。它还可以使类的派生更加复杂,因为虚拟基类是由最终的派生类初始化的,而不是(必要的)直接从它们继承的类


<>你只想在你特别想要一个钻石结构时,它必须是痛苦的,必须记住指定非虚拟继承以避免隐藏的开销。C++通常遵循的原则是不应该为你不需要的功能付费。Mund继承,但这是不必要的。考虑一个银行帐户,它是一个“Dalax PayMealEndoPoT”和一个“YayPayMeMeNoToPoT”,其中每一个都从“PayMutEnPoT”继承。成员。讨论为什么
virtual
不是自动的。@DavidSchwartz我错了。默认情况下使用虚拟继承会创建意外的共享并破坏封装。它还可以防止类成为POD。@RaymondChen:虽然答案非常相似,但我认为其他问题是关于虚拟成员的函数,而这个问题是关于虚拟继承的。虚拟继承不会避免菱形,它会创建菱形。