2010-03-16 120 views
2

在我的課的設計,我遇到了以下問題:抽象基類益智

class MyData 
{ 
    int foo; 
}; 

class AbstraktA 
{ 
public: 
    virtual void A() = 0; 
}; 

class AbstraktB : public AbstraktA 
{ 
public: 
    virtual void B() = 0; 
}; 

template<class T> 
class ImplA : public AbstraktA 
{ 
public: 
    void A(){ cout << "ImplA A()"; }  
}; 

class ImplB : public ImplA<MyData>, public AbstraktB 
{ 
public: 
    void B(){ cout << "ImplB B()"; } 
}; 

void TestAbstrakt() 
{ 
    AbstraktB *b = (AbstraktB *) new ImplB; 
    b->A(); 
    b->B(); 
}; 

上面的代碼的問題是,編譯器會抱怨AbstraktA :: A()沒有定義。

接口A被多個對象共享。但是A的實現依賴於模板參數。界面B是外界所見,需要抽象化。

我想這樣做的原因是,它會允許我這樣定義對象C: 定義C接口從巴丁格A. 繼承使用不同的數據類型的模板A.定義執行C

我希望我很清楚。有沒有辦法做到這一點,還是我需要重新考慮我的設計?

+0

我可能是愚蠢的,但爲什麼「抽象」拼寫「抽象」。那是故意的嗎? – 2010-03-16 10:20:18

+1

嘿,沒有理由。只是我的母語的結果:) – 2010-03-16 10:46:03

+0

可能的重複:http://stackoverflow.com/questions/254673/multiple-inheritance-from-two-derived-classes – Talvalin 2010-03-16 10:55:29

回答

9

你有兩條AbstracktA繼承路徑,你只在其中一個實現了AbstraktA :: A(),所以編譯器會抱怨。

您可能想要在兩種情況下虛擬地從AbstraktA繼承,以便只有一個AbstraktA基礎對象(在AbstraktA之前添加virtual)。

+0

謝謝您!!就這些。什麼是簡單的修復:)我記得現在我已經閱讀過虛擬繼承,但是因爲我從來沒有在實踐中使用它,所以我完全忘了它。 我擔心我不得不重新考慮我的設計,因爲我無法想出一個可以很好地解決這個問題的替代解決方案。再次感謝。 – 2010-03-16 10:43:39

+0

這工作,但導致的警告從編譯器: 「警告C4250:‘ImplB’:繼承‘ImplA :: ImplA :: A’通過主導」 這是一件值得關注? – Talvalin 2010-03-16 10:47:27

+0

@lalithv,如果那不是你想要的,這是值得關注的事情。在這種情況下,它就是想要的。 (我認爲這個警告屬於「不常見」,「最真實的誤報」,「通過重新組織錯誤肯定案例中的代碼難以避免」)。 – AProgrammer 2010-03-16 12:05:34

0

我忘了將虛擬析構函數添加到基類中。這導致我相信運行時malloc錯誤。

AbstraktB *b = new ImplB; 
b->A(); 
b->B(); 
delete b; 

在調試模式下,在delete語句,GCC給我: 的malloc:***錯誤對象0x60e2c4:指針被釋放沒有被分配

我解決了這個由基類更改爲:

class AbstraktA 
{ 
public: 
    virtual ~AbstraktA(){}; 
    virtual void A() = 0; 
}; 

class AbstraktB : virtual public AbstraktA 
{ 
public: 
    virtual ~AbstraktB(){}; 
    virtual void B() = 0; 
};