2017-07-04 55 views
5

我讀過很多地方的Java接口可以100%模擬使用C++的抽象類與所有純虛擬方法。C++中重疊的類java接口

我想這一塊的Java代碼轉換:

interface A { 
    void a(); 
} 

interface B extends A { 
    void b(); 
} 

class C implements A { 
    public void a() { 
    } 
} 

class D extends C implements B { 
    public void b() { 
    } 
} 

D d = new D(); 
d.a(); 
d.b(); 

到C++是這樣的:

class A { 
public: 
    virtual void a() const = 0; 
protected: 
    virtual ~A() { 
    } 
}; 

class B : public A { 
public: 
    virtual void b() const = 0; 
protected: 
    virtual ~B() { 
    } 
}; 

class C : public /*implements*/ A { 
public: 
    virtual void a() const override { 
    } 
}; 

class D : public /*extends*/ C, public /*implements*/ B { 
public: 
    virtual void b() const override { 
    } 
}; 

D d; 
d.a(); 
d.b(); 

但無論我怎麼努力,我總是落得C++抱怨模糊和/或缺少body定義。

這個想法是我想從「C」派生出來,它包含了所有類的一些共享代碼(這裏是:「D」但它們有更多),但仍然保持「D」與100%可互換的承諾任何實施「B」(包括「A」部分)的課程。

我與C++代碼上面得到的錯誤是:

../untitled1/main.cpp: In function ‘int main(int, char**)’: 
../untitled1/main.cpp:39:7: error: cannot declare variable ‘d’ to be of abstract type ‘D’ 
    D d; 
    ^
../untitled1/main.cpp:28:7: note: because the following virtual functions are pure within ‘D’: 
class D : public /*extends*/ C, public /*implements*/ B { 
    ^
../untitled1/main.cpp:7:18: note: virtual void A::a() const 
    virtual void a() const = 0; 
       ^
../untitled1/main.cpp:40:7: error: request for member ‘a’ is ambiguous 
    d.a(); 
    ^
../untitled1/main.cpp:7:18: note: candidates are: virtual void A::a() const 
    virtual void a() const = 0; 
       ^
../untitled1/main.cpp:23:18: note:     virtual void C::a() const 
    virtual void a() const override { 
       ^
+0

能否請您給我們一個[最小,*** ***完整,可驗證和示例](HTTP:// stackoverflow.com/help/mcve),幷包含* actual *錯誤(複製粘貼,完整,未經編輯)? –

+1

@Someprogrammerdude:代碼片段*是完整的,我想我不需要提供main()函數。我已經添加了編譯器輸出。 –

+1

您可能遇到*鑽石問題*。 –

回答

9

這是一個以虛擬繼承從A解決的問題。

class A { 
public: 
    virtual void a() const = 0; 
protected: 
    virtual ~A() { 
    } 
}; 

class B : public virtual A { 
public: 
    virtual void b() const = 0; 
protected: 
    virtual ~B() { 
    } 
}; 

class C : public virtual A { 
public: 
    virtual void a() const override { 
    } 
}; 

class D : public C, public B { 
public: 
    virtual void b() const override { 
    } 
}; 

的問題是,除非你指定兩個CB需要共享一個A子對象(所有派生類包含他們的基地作爲子對象),兩個子對象,你繼承都得到BC將不相關。

在你原來的計劃,通過CA提供給純虛成員執行不被認爲是在BA所需的相同功能的實現。

由於現在只有一個A子對象,所以此問題消失。但請注意,虛擬繼承並非沒有代價。所以想想如果你真的想要這樣的設計。

+1

SO最好。我嘗試了至少兩種不同的虛擬繼承方案,但因爲我只是模糊的想法,所以我失敗了。感謝您的代碼和解釋。 –

+0

您解決了鑽石問題 – Steephen

+0

@Steephen - 我敢說我不值得信任解決它。這是語言設計委員會提出的機制:) – StoryTeller

0

所有你需要的是執行的(d)中類:

class A { 
public: 
    virtual void a() const = 0; 
protected: 
    virtual ~A() { 
    } 
}; 

class B : public A { 
public: 
    virtual void b() const = 0; 
protected: 
    virtual ~B() { 
    } 
}; 

class C : public /*implements*/ A { 
public: 
    virtual void a() const override { 
    } 
}; 

class D : public /*extends*/ C, public /*implements*/ B { 
public: 
    void b() const override { 
    } 
    void a() const { 
     C::a(); 
    } 
}; 




int main() 
{ 
    D d; 
    d.a(); 
    d.b(); 
    return 0; 
} 
+1

這不會真的有助於在一個類(C)中共享通用代碼,是嗎?想象一下,你有20個類繼承像D. –

+0

因此,嘗試改變d類類似的東西: 類d:公共/ *寬*/C,公共/ *實現*/B { \t市民: \t \t無效B()const的覆蓋{ \t \t} (void)a()const {\t} \t \t} \t}; –