2012-01-27 172 views
4

我在C++中需要很少的继承帮助。我有这样的代码:在C++中实现接口

class IBase { 
public: 
    virtual long Dimensions() = 0; 
}; 

class IShape : public IBase { 
    virtual long Area() = 0; 
}; 

class Rectangle : public IShape { 
private: 
    long x; 
public: 
    long Dimensions() {return x}; 
    long Area() {return x*x}; 
}; 

class Rhombus: public IShape { 
private: 
    long x; 
    long fi; 
public: 
    long Dimensions() {return x}; 
    long Area() {return x*x*sin(fi)}; 
}; 

正如你所看到的,Dimensions()的实现对于这两个类都是相同的。现在我wan't做这样的事情:

class BaseImplementation : public IBase { 
protected: 
    long x; 
public: 
    virtual long Dimensions() {return x}; 
}; 

class Rectangle : public IShape, public BaseImplementation { 
public: 
    long Area() {return x*x}; 
}; 

class Rhombus: public IShape, public BaseImplementation { 
private: 
    long fi; 
public: 
    long Area() {return x*x*sin(fi)}; 
}; 

可以插入实现方法尺寸()成菱形类从BaseImplementation的?这在某些版本的C++标准中是否受到支持? Thx。

+0

@CharlesB这不是一般的坏主意分离接口继承和混合插件(缺省实现)。这是一种非常常见的技术。 – 2012-01-27 11:15:18

+0

@ user1173308你的意思是“插入类的方法的实现”究竟是什么意思?你想重写'Rhombus'类的'Dimensions()'的行为吗? – CharlesB 2012-01-27 11:15:26

+0

@KonradRudolph:谢谢,我不习惯这个。删除了评论,因为它是错误的。 – CharlesB 2012-01-27 11:16:54

回答

3

与层次的问题是,你Rectangle现在继承IBase两次:一次通过IShape,并通过BaseImplementation。称为Virtual Inheritance的C++功能旨在处理这种情况。请注意,您还需要使IShape继承IBasevirtual public

1

如果Dimensions()BaseImplementation中实现,并且在访问中至少为protected,则它应该对任何派生对象都可见。

所以Rhombus将能够使用Dimension()函数,如果它来自BaseImplementation。如果你想为Dimension()一个具体实施的Rhombus的情况下,你的Dimension()应该是virtual,你应该重写它Rhombus

+0

如果试图创建对象菱形。 GCC(g ++)显示此错误:不能将变量'xyz'声明为抽象类型'菱形'注:因为以下虚函数在'菱形'内是纯的:virtual long int IBase :: Dimensions() – zdenek 2012-01-27 11:35:00

0

没有必要显式插入实现。您可以调用 myRhombus-> Dimension(),因为它是继承的。

1

你可以简单地实现在之间的层定义尺寸:

class IBase { 
public: 
    virtual long Dimensions() = 0; 
}; 

class IShape : public IBase { 
public: 
    virtual long Area() = 0; 
}; 

class IShapesDefinedDimension : public IShape 
{ 
public: 
    long Dimensions() { return x; } 
protected: 
    long x; 
}; 

class Rectangle : public IShapesDefinedDimension { 
public: 
    long Area() {return x*x;} 
}; 

class Rhombus: public IShapesDefinedDimension { 
public: 
    long Area() {return x*x*sin(fi); } 
... 
    };