2017-07-04 63 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}; –