2017-02-09 102 views
0

我有一种“三角形继承”的问题,如果存在这样的事情。基本上,我有一个抽象基类中定义了一个接口,以及一个策略类定义实施一部分接口,就像这样:我可以使用其他父类的虚拟方法的实现吗

class System 
{ 
public: 
    Interface() = default; 
    virtual ~Interface() {} 

    virtual void doSomething() = 0; 
    virtual bool somethingDone() const = 0; 

    virtual int trait1() const = 0; 
    virtual bool trait2() const = 0; 
}; 

class SomethingImplementation 
{ 
public: 
    SomethingImplementation() = default; 
    void doSomething() { (void)0; } 
    bool somethingDone() { return true; } 
}; 

然后,我有不同的接口的几种实现案例。在某些情况下,我想用简单的实现,而在其他我想自定义他们

class SystemA : public System, public SomethingImplementation {/*...*/}; 
class SystemB : public System, public SomethingImplementation {/*...*/}; 
class SystemC : public System, { /* with a custom implementation ... */ }; 

我无法弄清楚什么是类系统A或系统B的细节可能是什么使实施工作

http://cpp.sh/73r5

解决方案1 ​​

using语句,似乎不这样做在这种情况下,任何东西。

http://cpp.sh/2nhki

59:13: error: cannot declare variable 'a' to be of abstract type 'SystemA' 
22:7: note: because the following virtual functions are pure within 'SystemA': 
6:18: note:  virtual void System::doSomething() 
7:18: note:  virtual bool System::somethingDone() const 
60:13: error: cannot declare variable 'b' to be of abstract type 'SystemB' 
31:7: note: because the following virtual functions are pure within 'SystemB': 
6:18: note:  virtual void System::doSomething() 
7:18: note:  virtual bool System::somethingDone() const 
63:38: error: invalid new-expression of abstract class type 'SystemA' 

解决方案2

添加一个额外的接口类。创建一个SomethingInterface类,并从SomethingInterface继承InterfaceSomethingImplementation。这将问题转化为常见的“钻石继承”问题,但我仍然无法让编译器做我想做的事情。

http://cpp.sh/3dxab

什么是使用来自另一大类实施一个父类的虚方法的方法是什么?

+0

尝试虚拟继承:'类SystemA:公共系统,公共虚拟SomethingImplementation','类系统:公共虚拟SomethingInterface'等。 –

+0

相同的错误http://cpp.sh/7kroo –

+1

虚拟继承与此无关。 SomethingInterface和System没有共同的祖先类。 –

回答

0

我相信你想要做这样的事情。

// The interface. 
class IInterface 
{ 
public: 
    virtual ~IInterface() {} 
    virtual void method1() = 0; 
    virtual void method2() = 0; 
}; 

// A partial, abstract implementation of interface. 
// This base class implements method1 but leaves method2 unimplemented, 
// which means this class cannot be instantiated. 
class PartialImplementation : public IInterface 
{ 
public: 
    virtual void method1() {} 
}; 

// Full implementation that uses the partial implementation above. 
// method1's implementation is from the base class. 
// method2's implementation is in this class. 
// Because all methods are implemented (directly or inherited), this class can be instantiated. 
class FullImplementation1 : public PartialImplementation 
{ 
public: 
    void method2() {} 
}; 

// Full implementation that uses the partial implementation above. 
// method1's implementation is in this class (overrides base implementation). 
// method2's implementation is in this class. 
// Because all methods are implemented (directly), this class can be instantiated. 
class FullImplementation2 : public PartialImplementation 
{ 
public: 
    void method1() {} 
    void method2() {} 
}; 

// Full implementation that DOES NOT use the partial implementation above. 
// method1's implementation is in this class. 
// method2's implementation is in this class. 
// Because all methods are implemented (directly), this class can be instantiated. 
class FullImplementation3 : public IInterface 
{ 
public: 
    void method1() {} 
    void method2() {} 
}; 

int main() 
{ 
    FullImplementation1 i1; // OK 
    FullImplementation2 i2; // OK 
    FullImplementation3 i3; // OK 

    IInterface* p1 = new FullImplementation1(); // OK 
    delete p1; // OK 

    IInterface* p2 = new FullImplementation2(); // OK 
    delete p2; // OK 

    IInterface* p3 = new FullImplementation3(); // OK 
    delete p3; // OK 

    return 0; 
} 
+0

请注意,您也可以有'PartialImplementation',它不实现接口。那么你必须在完整的实现中明确地实现接口,并且这些方法的实现可以调用基于部分实现的方法。 –

+0

另外:正如其他评论者所提到的,您在这里没有钻石继承,并且您不需要虚拟继承。如果你有_multiple_部分实现,你试图用作一个完整实现的基础,那么你可以使用虚拟继承来产生钻石继承。 –

0

我看到钻石继承的每一个例子都来自坏的设计,因为对IS-A和HAS-A关系的误解。不要继承以使用实现,继承以提供实现(例如,继承以实现)。

SystemA应从System继承,并将SomethingImplementation作为其调用方法的成员。

你也可以看看mixin。

+0

感谢您的简要描述。这正是我所做的。我看着mixin,看起来它不是我想要的。我想现在是我现在购买Alexandrescu的书的时候了 –

相关问题