首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这设计不好吗?

这设计不好吗?
EN

Stack Overflow用户
提问于 2014-05-23 11:48:27
回答 4查看 141关注 0票数 0
代码语言:javascript
复制
class IStreamMetadata{
public:
    virtual DataStreamType getType() = 0;
    virtual int getMaxFieldSize()  = 0;
    virtual SourceType getSourceType() = 0;
    virtual void setType(DataStreamType dsType) = 0;
    virtual void setSourceType(SourceType )= 0;
    virtual void setMaxFieldSize(int size) = 0;
};

class IFileMetadata: public IStreamMetadata{
public: 
    virtual string getPath() = 0;
    virtual void setPath(string path) = 0;
};

class ISocketMetadata: public IStreamMetadata{
public:
    virtual int getPort() = 0;
};

class ColumnDBMetadata: public IStreamMetadata, public IFileMetadata, public ISocketMetadata

ColumnDBMetadata是从包含这3个类(IStreamMetadataIFileMetadataISocketMetadata)的表数据库中检索的类。

编译器给了我一个警告

代码语言:javascript
复制
C4584: 'ColumnDBMetadata' : base-class 'IStreamMetadata' is already a base-class of 'IFileMetadata'.

ColumnDBMetata中创建方法更好,比如getStreamMetadatagetFileMetadatagetSocketMetadata。或者将ColumnDBMetadata传递给创建正确接口的工厂?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-05-23 12:21:03

我不打算评论语义学。只要您继承的所有类都是纯虚拟的,这是C++拥有接口的方式,这个设计的形状应该很好,但是,您犯了一个错误。

您的继承应该如下所示:

代码语言:javascript
复制
class IFileMetadata: public virtual StreamMetadata

class ISocketMetadata: public virtual IStreamMetadata

class ColumnDBMetadata: public virtual IStreamMetadata, public virtual IFileMetadata, public virtual ISocketMetadata

虚拟关键字所做的是将所有重复继承的函数定义融合在一起。如果不这样做,编译器会认为您继承的是同名的不同函数,这就是为什么您会收到警告。

基本上,您应该养成将纯虚拟“接口”类继承为

public virtual

另外,您还需要在所有这些接口类中编写一个空的内联虚拟析构函数,因为即使类什么都不做,语言也希望有一个在那里。

请注意,这个设计是好的,因为您只有纯粹的虚拟方法,而没有其他。如果要在任何继承的类中添加字段或单个已实现的函数(除析构函数外),这将是正确的多重继承,如果您愿意这样做,最好先花大量时间搜索主题。

票数 1
EN

Stack Overflow用户

发布于 2014-05-23 11:51:04

有股气味..。列如何实现流、文件和套接字?看起来它可能是这些类的使用者,但不是与生俱来的。

让人困惑的是,您的基本流interface (我知道它是一个从C++角度看的接口而不是真正的接口!)没有公开足够的通用功能来使其有用。您的文件和套接字接口实现了不同的语义。您需要一个更通用的接口,即文件/套接字实现,然后只需要将基本接口传递给ColumnDBMEtaData的构造函数,它可以随意使用它,因为您已经混淆了实现。

还可以考虑将其添加到基本接口类中:

代码语言:javascript
复制
virtual ~IStreamMetaData() = 0 { };
票数 4
EN

Stack Overflow用户

发布于 2014-05-23 12:03:18

是的,这是糟糕的设计。大多数人都会理解这个class ColumnDBMetadata: public IStreamMetadata, public IFileMetadata, public ISocketMetadata,这意味着ColumnDBMetadata的实例是,同时是

如果您想要摆脱所有继承,那么您拥有getStreamMetadata, getFileMetadata, getSocketMetadata的想法是可以的。

另一种方法是逆转您建议的层次结构:使DB类基接口具有套接字、流和文件元数据继承它。因此,您首先创建DB类(通过工厂),确定它是什么,然后将它降为特定类型之一。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23828443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档