7

讓我們假設一些(舊的)代碼,這不能觸及,申報使用姐妹繼承

struct B{ 
public: 
    void f(){} 
}; 

,讓我們假設有

struct A{ 
public: 
    virtual void f()=0; 
}; 

是有可能使一個子類調用B ::˚F沒有顯式調用F(),即代替

struct C: public A, public B{ 
    void f(){ 
    B::f(); 
    } 
}; 

有類似

struct C:virtual public A,virtual public B{ 

}; 

(注意,這最後一類是抽象的,對於沒有定義:: F中的編譯器)

+2

'B :: f()'有什麼問題?這是調用'B :: f()'的正確方法。 – 2012-04-10 05:47:54

+0

想象你有100個函數;) – 2012-04-10 05:49:54

+2

不,基本成員函數沒有辦法爲另一個基類實現純虛函數。那根本行不通。你有什麼是好的。 – 2012-04-10 05:53:23

回答

1

直接在C++中,這是不可能基於的B的功能A的一些隱式匹配到多態調度。您可以使用gccxml或其他類似產品進行某種代碼生成,但是如果只有一百個函數,宏可以將轉發減少爲一行代碼 - 不值得引入額外的工具,除非您擁有數千和數千這些要做。

+0

「_dispatch多態基於B的函數與A's_的某種隱式匹配」G ++ _used_支持所謂的「簽名」:[使用簽名類型抽象](http://gcc.gnu.org/onlinedocs/gcc-2.95 .3/gcc_5.html#SEC112)「在GNU C++中,你可以使用關鍵字簽名來定義一個完全抽象的類接口作爲數據類型,你可以使用簽名指針連接這個抽象類和實際類。獨立於繼承(...)簽名允許您使用現有的類層次結構作爲簽名類型的實現。「 – curiousguy 2012-07-26 10:25:48

+0

@curiousguy:這是一般性的(gcc 3中歷史給定的刪除)興趣,但我不明白它是如何用於做問題尋找的或者更普遍的是「基於B的函數的某些隱式匹配A的「你引用。給定'簽名S {void f(); }; ... S * p = static_cast (this); p-> f();'似乎在功能上等價於說'std :: function x = std :: bind(&B :: f,this); x();' - 這兩個看起來都比在問題中調用'B :: f();'笨拙。不知道我是否錯過了什麼......? – 2014-11-06 23:50:54

0

你可以這樣做:

void C::f() { 
    B* b = this; 
    b->f(); 
} 
+0

謝謝,但是,我不想寫每個函數的實現(此外,這個版本比我寫的有什麼好處?) – 2012-04-10 06:02:14

+0

@FabioDallaLibera:我不明白。如果你不想在'C'中寫一個名爲'f'的函數,那你爲什麼要聲明這樣一個函數?在這種情況下,'C :: f'的這個實現和你的這個實現沒有什麼區別,除了這個不使用你想要避免的'B :: f'。 – 2012-04-10 06:31:12

0

不,你不能做那。從你給我們看的片段看起來,B應該是C的成員,而不是繼承。您只需編寫一些轉發功能(或自動爲您生成腳本的腳本)。

1

使A委託給B實現:

class A_Impl : public A 
{ 
public: 
    virtual void f() 
    { 
     b.f(); 
    } 
private: 
    B b; 
} 

A_Impl派生實現C

class C: public A_Impl 
{ 
}; 

或者,如果你只是想顯示A繼承層次結構,派生公開從A,私下從A_Impl

class C: public A, private virtual A_Impl 
{ 
}; 
-1

所以,你有一個100個%純虛函數,在B這些功能的實現,並且要避免寫,再實現所有這些功能在C調用B.有沒有辦法讓編譯器使用B的實現是自動的。而不是與編譯器作戰(每次都會丟失!),重新考慮繼承圖。也許使B成爲A的一個子類,然後從B中推導出C,或者將B中的100個方法和因子分解爲A的具體子類。

編程是在您的工具提供的約束範圍內解決問題的技術。如果發現自己與工具不一致,則需要重新考慮對問題的處理方式或使用不同的工具。

+0

問題說B不能被觸及,所以你不能將它作爲A的子類,並且你不能將方法移出它。 – Karu 2012-04-13 11:19:02