簡體   English   中英

多重繼承

[英]Multiple Inheritance

#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.

}

上面的foo調用是編譯時錯誤。 我想用obj的B部分調用foo而不使用虛擬繼承。 我怎么做。

同樣,在虛擬繼承的情況下,為什么需要將偏移量信息存儲在vtable中。 這可以在編譯時自行確定。 在上述情況下,如果我們將foo與D的對象一起傳遞,則僅在編譯時才能計算D的A部分的偏移量。

繼承兩次

對於雙重繼承,您會產生歧義-編譯器無法知道您要使用兩個A基。 如果要有兩個A底(有時可能需要這樣做),則可以通過強制轉換為B或C在它們之間進行選擇。這里默認轉換中最合適的是static_cast (作為最弱的可用),但是它是因為您沒有轉換為派生類型,所以不需要(它確實比案例需要更強大)。 一個自定義的safe_cast模板應該可以完成以下工作:

/// 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.

}

編譯時間類型-使用模板

同樣,在虛擬繼承的情況下,為什么需要將偏移量信息存儲在vtable中。 這可以在編譯時自行確定。 在上述情況下,如果我們將foo與D的對象一起傳遞,則僅在編譯時才能計算D的A部分的偏移量。

這是一個誤解。 現在編寫的foo函數除了是A *之外,沒有關於ptr類型的編譯類型信息,即使您傳遞B *或C *也是如此。 如果希望foo能夠根據傳遞的編譯時間進行操作,則需要使用模板:

template <class TypeDerivedFromA>
int foo(TypeDerivedFromA *ptr)
{
  ptr->eat();
}

虛擬繼承

您的問題提到虛擬繼承。 如果要使用虛擬繼承,則需要指定:

class B: public virtual A ...

class C: public virtual A ...

使用此代碼可以編譯,但是使用此解決方案,您將無法在B :: A或C :: A(只有一個A)之間進行選擇,因此這可能與您無關。

虛擬功能

此外,您的問題似乎混淆了兩個不同的概念:虛擬繼承(這意味着在兩個中間基類之間共享一個基類)和虛函數(這意味着允許通過基類指針調用派生類函數)。 如果希望使用A指針調用B :: eat,則可以使用虛擬函數來執行此操作,而無需進行虛擬繼承(實際上,虛擬繼承會阻止您這樣做,如上所述)。

class A
{
   int a;
   int b;

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

如果您不接受虛擬函數,則如上所述,其編譯時機制是模板。

使用static_cast -這里需要static_cast繼承。

main()
{
  D obj;
  foo(static_cast<B*>(&obj));
}

首先, obj沒有名為B的成員。它從B繼承,這意味着它繼承了B的所有成員。

您可以致電:

foo(static_cast<B*>(&obj));
使它工作。

我認為static_cast不會起作用。

使用foo函數時,無論您作為參數傳遞哪種類型,編譯器都知道您有一個指向A的指針。

如果您不使用虛擬繼承,那么我認為無法從指向A的指針調用B函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM