C++ 多重继承

C++ 多重继承,c++,inheritance,multiple-inheritance,C++,Inheritance,Multiple Inheritance,上面的foo调用是一个编译时错误。 我想用obj的B部分调用foo,而不使用虚拟继承。我该怎么做呢 另外,在虚拟继承的情况下,为什么偏移量信息需要存储在vtable中。这可以在编译时确定。在上面的例子中,如果我们用D的对象传递foo,在编译时我们只能计算D的A部分的偏移量 使用施法-这里需要静态施法来施展继承权 #include<iostream> using namespace std; class A { int a; int b; public: v

上面的foo调用是一个编译时错误。 我想用obj的B部分调用foo,而不使用虚拟继承。我该怎么做呢

另外,在虚拟继承的情况下,为什么偏移量信息需要存储在vtable中。这可以在编译时确定。在上面的例子中,如果我们用D的对象传递foo,在编译时我们只能计算D的A部分的偏移量

使用施法-这里需要静态施法来施展继承权

#include<iostream>
using namespace std;

class A

{
   int a;
   int b;
   public:
   void eat()
   {
      cout<<"A::eat()"<<endl;
   }
};

class B: public A
{
   public:
   void eat()
   {

      cout<<"B::eat()"<<endl;

   }

};

class C: public A
{

   public:
   void eat()

   {

      cout<<"C::eat()"<<endl;

   }

};

class D: public B, C
{

};

int foo(A *ptr)
{

ptr->eat();

}
main()
{

D obj;
foo(&(obj.B)); //error. How do i call with D's B part.

}
首先,obj没有名为B的成员。它从B继承,这意味着它将B的所有成员作为自己的成员继承

你可以致电:

使其工作。

继承两次 使用双重继承会产生歧义——编译器无法知道要使用两个A基中的哪一个。如果您想有两个A基,有时您可能想这样做,您可以通过强制转换到B或C来在它们之间进行选择。这里最合适的默认强制转换是静态强制转换,因为它是最脆弱的可用类型,但是它不是真正需要的,它仍然比您的案例需要更强,因为您没有强制转换到派生类型。自定义安全强制转换模板应执行以下操作:

foo(static_cast<B*>(&obj));
有了这个,代码就可以编译了,但是有了这个解决方案,您无法在B::A或C::A之间进行选择,因为只有一个A,因此这可能不是您想要的

虚拟函数 此外,您的问题似乎混淆了两个不同的概念,虚拟继承意味着在两个中间基类之间共享一个基类,虚拟函数意味着允许通过基类指针调用派生类函数。如果希望使用指针调用B::eat,可以在不使用虚拟继承的情况下执行此操作。实际上,虚拟继承会阻止您使用虚拟函数执行此操作,如上所述:

class B: public virtual A ...

class C: public virtual A ...

如果您不能接受虚拟函数,那么编译时机制就是模板,如上所述。

我认为静态转换不起作用

当您使用foo函数时,编译器只知道您有一个指向的指针,不管您作为参数传递的类型是什么


如果不使用虚拟继承,那么我认为没有办法从指向a的指针调用B函数。

我怎么做。在编辑模式下,它正确显示。选择代码,然后用1和0按下按钮。如果foo不是虚拟的,则用obj的B、C或A部分调用foo将得到相同的结果。答:eat在任何情况下都会打印出来。吕克,你说得对;我忘了加那个。D类:公共B,C。你真的想保持B类的可见性模式为私有吗?不提及任何内容都会导致它在私有可见性模式下被继承。Suma,虚拟函数的vtable和虚拟继承相同吗?如果没有,虚拟继承表包含什么。使用虚拟继承时,虚拟表布局和调用虚拟函数的机制稍微复杂一些。看-但要做好准备,这是一个高级主题,理解它需要努力和耐心。
/// cast using implicit conversions only
template <class To,class From>
inline To safe_cast( const From &from ) {return from;}

main()
{

  D obj;
  foo(safe_cast<B *>(&obj)); //error. How do i call with D's B part.

}
template <class TypeDerivedFromA>
int foo(TypeDerivedFromA *ptr)
{
  ptr->eat();
}
class B: public virtual A ...

class C: public virtual A ...
class A
{
   int a;
   int b;

   public:
   virtual void eat()
   {
      cout<<"A::eat()"<<endl;
   }
};