2015-09-04 99 views
0

令我惊讶的是,下面的C++代码无法编译。抽象类型“ImplementationB”的如何继承纯虚函数的实现C++

class InterfaceA { 
public: 
    virtual void Foo() = 0; 
}; 

class InterfaceB : public InterfaceA { 
public: 
    virtual void Bar() = 0; 
}; 

class ImplementationA : public InterfaceA { 
public: 
    void Foo() override {} 
}; 

class ImplementationB : public ImplementationA, public InterfaceB { 
public: 
    void Bar() override {} 
}; 

int main() { 
    ImplementationB b; 
    b.Bar(); 
} 

对象是不允许的: 纯虚函数“了InterfaceA ::富”不具有置换器。 错误C2259'ImplementationB':无法实例化抽象类。

是否可以继承实现一个纯虚方法的实现而不ImplementationB重新定义foo方法为:

void Foo() override { 
    ImplementationA::Foo(); 
} 

如果没有的话,为什么?

+0

C++是从Java不同。之前已经有过几次这样的问题。 –

+0

我认为这里的答案比上面引用的重复中的答案要好。这些答案没有提到虚拟继承,因为在另一个问题中指定的问题不会从具有共同祖先的类继承,因为问题在这里。这些问题并不完全相同(并且这个答案解决了我在这里找到我的方式时遇到的问题,而另一个则没有)。 –

回答

2

你有钻石问题。因此,您应该使用虚拟继承。

正确的代码:

class InterfaceA { 
public: 
    virtual void Foo() = 0; 
}; 

class InterfaceB : public virtual InterfaceA { 
public: 
    virtual void Bar() = 0; 
}; 

class ImplementationA : public virtual InterfaceA { 
public: 
    void Foo() override {} 
}; 

class ImplementationB : public ImplementationA, public InterfaceB { 
public: 
    void Bar() override {} 
}; 

int main() { 
    ImplementationB b; 
    b.Bar(); 
} 
3

是的,为了实现你需要的东西,你需要使用虚拟连接。

一些细节: 现在,你的ImplementationB有两个父母,每个父母都是InterfaceA的独立后代。因此,在ImplementationB中有两个InterfaceA副本 - 一个是从ImplementationA继承的并且具有Foo()重写的,另一个是从InterfaceA继承的,并且没有Foo重写。虚拟继承(不要与虚拟功能混淆!)将确保您只有一个副本 - 一切都被覆盖的副本。