classAnimal{public:virtualvoideat();};classMammal:publicAnimal{public:virtualvoidbreathe();};classWingedAnimal:publicAnimal{public:virtualvoidflap();};// A bat is a winged mammalclassBat:publicMammal,publicWingedAnimal{};Batbat;
classAnimal{public:virtualvoideat();};// Two classes virtually inheriting Animal:classMammal:publicvirtualAnimal{public:virtualvoidbreathe();};classWingedAnimal:publicvirtualAnimal{public:virtualvoidflap();};// A bat is still a winged mammalclassBat:publicMammal,publicWingedAnimal{};
Microsoft Visual C++与g++不同,把类的虚函数与虚基类地址偏移值分别放入了两个虚表中,前者称为虚函数表vftbl,后者称虚基类表vbtbl。因此一个类实例可能有两个虚指针分别指向类的虚函数表与虚基类表,这两个虚指针分别称为虚函数表指针vftbl与虚基类表指针vbtbl。当然,类实例也可以只有一个虚指针,或者没有虚指针。虚指针总是放在类实例的数据成员之前,且虚函数表指针总是在虚基类表指针之前。因而,对于某个类实例来说,如果它有虚基类指针,那么虚基类指针可能在类实例的0字节偏移处,也可能在类实例的4字节偏移处(对于32位程序来说),这给类成员函数指针的实现带来了很大麻烦。
template<typenameT>classMakeFinally{private:MakeFinally(){};//只有MakeFinally的友类才可以构造MakeFinally~MakeFinally(){};friendT;};classMyClass:publicvirtualMakeFinally<MyClass>{};//MyClass是不可派生类//由于虚继承,所以D要直接负责构造MakeFinally类,从而导致编译报错,所以D作为派生类是不合法的。classD:publicMyClass{};//另外,如果D类没有实例化对象,即没有被使用,实际上D类是被编译器忽略掉而不报错intmain(){MyClassvar1;// D var2; //这一行编译将导致错误,因为D类的默认构造函数不合法}
^Andrei Milea. Solving the Diamond Problem with Virtual Inheritance. http://www.cprogramming.com/: Cprogramming.com. [2010-03-08]. (原始内容存档于2021-03-04). One of the problems that arises due to multiple inheritance is the diamond problem. A classical illustration of this is given by Bjarne Stroustrup (the creator of C++) in the following example:
^Ralph McArdell. C++/What is virtual inheritance?. http://en.allexperts.com/: All Experts. 2004-02-14 [2010-03-08]. (原始内容存档于2010-01-10). This is something you find may be required if you are using multiple inheritance. In that case it is possible for a class to be derived from other classes which have the same base class. In such cases, without virtual inheritance, your objects will contain more than one subobject of the base type the base classes share. Whether this is what is the required effect depends on the circumstances. If it is not then you can use virtual inheritance by specifying virtual base classes for those base types for which a whole object should only contain one such base class subobject.