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 ISocketMetadataColumnDBMetadata是从包含这3个类(IStreamMetadata、IFileMetadata、ISocketMetadata)的表数据库中检索的类。
编译器给了我一个警告
C4584: 'ColumnDBMetadata' : base-class 'IStreamMetadata' is already a base-class of 'IFileMetadata'.在ColumnDBMetata中创建方法更好,比如getStreamMetadata、getFileMetadata、getSocketMetadata。或者将ColumnDBMetadata传递给创建正确接口的工厂?
发布于 2014-05-23 12:21:03
我不打算评论语义学。只要您继承的所有类都是纯虚拟的,这是C++拥有接口的方式,这个设计的形状应该很好,但是,您犯了一个错误。
您的继承应该如下所示:
class IFileMetadata: public virtual StreamMetadata
class ISocketMetadata: public virtual IStreamMetadata
class ColumnDBMetadata: public virtual IStreamMetadata, public virtual IFileMetadata, public virtual ISocketMetadata虚拟关键字所做的是将所有重复继承的函数定义融合在一起。如果不这样做,编译器会认为您继承的是同名的不同函数,这就是为什么您会收到警告。
基本上,您应该养成将纯虚拟“接口”类继承为
public virtual
另外,您还需要在所有这些接口类中编写一个空的内联虚拟析构函数,因为即使类什么都不做,语言也希望有一个在那里。
请注意,这个设计是好的,因为您只有纯粹的虚拟方法,而没有其他。如果要在任何继承的类中添加字段或单个已实现的函数(除析构函数外),这将是正确的多重继承,如果您愿意这样做,最好先花大量时间搜索主题。
发布于 2014-05-23 11:51:04
有股气味..。列如何实现流、文件和套接字?看起来它可能是这些类的使用者,但不是与生俱来的。
让人困惑的是,您的基本流interface (我知道它是一个从C++角度看的接口而不是真正的接口!)没有公开足够的通用功能来使其有用。您的文件和套接字接口实现了不同的语义。您需要一个更通用的接口,即文件/套接字实现,然后只需要将基本接口传递给ColumnDBMEtaData的构造函数,它可以随意使用它,因为您已经混淆了实现。
还可以考虑将其添加到基本接口类中:
virtual ~IStreamMetaData() = 0 { };发布于 2014-05-23 12:03:18
是的,这是糟糕的设计。大多数人都会理解这个class ColumnDBMetadata: public IStreamMetadata, public IFileMetadata, public ISocketMetadata,这意味着ColumnDBMetadata的实例是,同时是。
如果您想要摆脱所有继承,那么您拥有getStreamMetadata, getFileMetadata, getSocketMetadata的想法是可以的。
另一种方法是逆转您建议的层次结构:使DB类基接口具有套接字、流和文件元数据继承它。因此,您首先创建DB类(通过工厂),确定它是什么,然后将它降为特定类型之一。
https://stackoverflow.com/questions/23828443
复制相似问题