请教接口与实现继承问题(重赏100分)

WilliamJ 2006-04-25 09:22:13
我有一个接口抽象类:Shape 有个纯虚函数:virtual Shape_Type getShapeType() = 0;,它的实现类为:ShapeImp 提供了函数:getShapeType();的实现.又有个接口抽象类:BoxShape为Shape的派生类,它有个纯虚函数:virtual float getHeight() = 0;BoxShape的实现类为:BoxShapeImp.
我的问题就是,我想让BoxShapeImp类既有已经具有实现的getShapeType()函数又可以在自身中实现getHeight()函数,BoxShapeImp类该怎么继承???用多重继承的话,像这样:class BoxShapeImp : public ShapeImp,public BoxShape {};这样实际上BoxShapImp还是一个抽象类,因为它继承的BoxShape是继承Shape,而Shape是类抽象类,所以Shape中的getShapeType()在BoxShapeImp中找不到实现代码,是无法编译通过的,我已经测试过了,但是如果我在BoxShapeImp实现了getShpeType()函数就可以编译通过,但这个函数已经在ShapeImpe类中实现了,并且我是继承了这个类的,这样getShpaeType()就要编两遍代码来实现,这种做法显然不合适.
各位大侠帮我想想有没有其它设计方法,可以解决这个问题,帮帮我,谢谢.
...全文
343 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
ccccffff 2006-04-27
  • 打赏
  • 举报
回复
up
WilliamJ 2006-04-27
  • 打赏
  • 举报
回复
xzgyb(老达摩) ( ) 信誉:110
再次谢谢这位兄台的建议,定义成Shape,确实是结构比较清晰了,但Shape只能定义成对象指针了,管理起来增加了一点点难度.
xzgyb 2006-04-27
  • 打赏
  • 举报
回复
WilliamJ(威廉J),呵,不必客气,好久没有人叫我同学了,哈

同意rickerliang(),有点像Bridge模式了
BoxShapeImp类中不要定义ShapeImp,而是Shape,
一切面向接口编程
这样也可能演化成Decorator模式了
看你怎么设计了
rickerliang 2006-04-27
  • 打赏
  • 举报
回复
难道要用bridge??
哈哈
sharpdew 2006-04-27
  • 打赏
  • 举报
回复
照你这样,还不如把ShapeImp扔掉,在Shape里面写个默认得的私有实现函数呢,既简洁又高效,呵呵!
其实你这样的问题,过于片面化,或者说你没有把整个问题展开,难以让人家知道你整个实现的意图,到底是要高效呢,还是要易于扩展呢,或者别的
WilliamJ 2006-04-27
  • 打赏
  • 举报
回复
在此,深深的对 xzgyb(老达摩) 同学表示感谢,你的解决方案是到目前为止唯一可行的方案,但我有一些想法可以讨论一下,我认为虚拟继承对于性能的开销非常大,而且多继承大幅增加了设计难度,我自己突然有了一个想法,就是使用分层法,让BoxShapeImp只从BoxShape继承,而不从ShapeImp继承,而是在BoxShapeImp类中定义一个ShapeImp的对象,然后在BoxShapeImp中被重载的函数getType()中调用ShapeImp.getType()函数,这样也能达到目的,呵呵.
xzgyb 2006-04-27
  • 打赏
  • 举报
回复
其中
class BoxShapeImpl : public ShapeImpl
我觉得ShapeImpl为实现,
最好为
class BoxShapeImpl : private ShapeImpl
java中像这种方式很正常
但c++中由于多重继承使得ShapeImpl, BoxShape都有Shape基类,
如果不用虚拟继承,
而在BoxShapeImpl没有实现getShapeType方法
则BoxShapeImpl仍然被认为是抽象的
书上写的是优先用组合,然后再用继承
你可以考虑考虑
xzgyb 2006-04-27
  • 打赏
  • 举报
回复
可以用虚基类,不过vc6给个警告

#include <iostream>
#include <fstream>

using namespace std;

class Shape
{
public:
virtual int getShapeType() = 0;
};

class ShapeImpl : virtual public Shape
{
public:
virtual int getShapeType()
{
cout << "ShapeImpl::getShapeType\n";
return 1;
}
};

class BoxShape : virtual public Shape
{
public:
virtual float getHeight() = 0;
};

class BoxShapeImpl : public ShapeImpl, public BoxShape
{
public:
virtual float getHeight()
{
cout << "BoxShapeImpl::getHeight\n";
return 1.0;
}
};

int main()
{
Shape * pShape = new BoxShapeImpl;

pShape->getShapeType();

return 0;
}

skywoody 2006-04-26
  • 打赏
  • 举报
回复
接口用public继承,实现用private继承
du51 2006-04-26
  • 打赏
  • 举报
回复
能不能嵌套类..
呵呵..猜的.
WilliamJ 2006-04-26
  • 打赏
  • 举报
回复
我之所以不让BoxShape继承于ShapeImp是以为这样接口特性就破坏了,暴露了整个实现?
我希望大家能给我建议一个更好的设计.
wengerbin 2006-04-26
  • 打赏
  • 举报
回复
我也认为你这样一来做很不好,结构比较乱,即使是用如楼上所说的"接口用public继承,实现用private继承"还是乱.并且 virtual float getHeight() 这个方法也成了私有了.建议你不要这么用
howyougen 2006-04-26
  • 打赏
  • 举报
回复
图怎么乱了
shape
*::getshapetype(虚)
^
/ \
/ \
/ \
boxshape(虚) shapeimp
*::getheight (*::getshapetype)
^
|
boxshapeimp
(*::getheight)
howyougen 2006-04-26
  • 打赏
  • 举报
回复
shape
*::getshapetype(虚)
^
/ \
/ \
/ \
boxshape(虚) shapeimp
*::getheight (*::getshapetype)
^
|
boxshapeimp
(*::getheight)

你的继承图是不是上面的那个?
那为啥boxshape不从shapeimp继承呢?
或者shape如果是纯虚 的话,为啥还有一个shapeimp?
WilliamJ 2006-04-26
  • 打赏
  • 举报
回复
JohnTitor(贱畜) ( ) 信誉:100
这位兄台的做法更不不行,你想啊,我最终提供给客户的只有抽象接口类,即Shape,BoxShape等,如果像你所说的,把Box作为一个独立的类,使他和Shpae没有任何关系,那么客户怎么通过Box接口来操纵Shape中的共有的函数呢,比如getType() ???
JohnTitor 2006-04-26
  • 打赏
  • 举报
回复
或者独立出一个抽象类Box,这个类只有一个getHeight虚函数,然后让BoxShapeImpl多重继承ShapeImpl和Box,即BoxShapeImpl: public Box,public ShapeImpl
JohnTitor 2006-04-26
  • 打赏
  • 举报
回复
让BoxShape继承ShapeImpl?
WilliamJ 2006-04-26
  • 打赏
  • 举报
回复
sharpdew(风刃) ( ) 信誉:100
再次谢谢你的回复,但还是相差甚远,你还是没理解我的意思,你在接口Base2里实现了Type()函数,那么我还定义接口干什么?我定义接口的目的就是隐藏具体实现,但你确把具体实现放到了接口抽象类中......
sharpdew 2006-04-26
  • 打赏
  • 举报
回复
既然上面我看错题了,那给你一个新的,呵呵:

class Base1
{
public:
virtual void Type() = 0;

};

class Base2 : public Base1
{
public:
virtual void Name() = 0;

virtual void Type()
{
cout << "Base2" << endl;
}

};

class Sub1 : public Base1
{
public:
virtual void Type()
{
cout << "Sub1" << endl;
}
};

class Sub2 : public Sub1, Base2
{
public:
virtual void Name()
{
cout << "Sub2" << endl;
}

virtual void Type()
{
Sub1::Type();
}
};

int main()
{
Sub2 c;
c.Type();
c.Name();

return 0;
}

输出:
Sub1
Sub2

WilliamJ 2006-04-25
  • 打赏
  • 举报
回复
sharpdew(风刃) ( ) 信誉:100
很感谢你的回复,但有个地方和我的要求有很大的出入,那就是:我想的是程序中的Base2继承于Base1,就像我文中提到的BoxShape继承于Shape一样,如果这样一改,你的程序就无法通过了,sub2变成了抽象类,因为sub2继承的base2是继承于base1的!!!这样的话就会出现我的文中提到的问题了--那就是:virtual void Type()需要在两处编写实现代码,一处在sub1中,一处在sub2中.
加载更多回复(6)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧