Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这是一个糟糕的设计吗?_C++_Oop_Design Patterns - Fatal编程技术网

C++ 这是一个糟糕的设计吗?

C++ 这是一个糟糕的设计吗?,c++,oop,design-patterns,C++,Oop,Design Patterns,columndMetadata是一个从包含这三个类的信息的表数据库中检索的类(IStreamMetadata,IFileMetadata,ISocketMetadata) 编译器给了我一个警告 class IStreamMetadata{ public: virtual DataStreamType getType() = 0; virtual int getMaxFieldSize() = 0; virtual SourceType getSourceType() =

columndMetadata
是一个从包含这三个类的信息的表数据库中检索的类(
IStreamMetadata
IFileMetadata
ISocketMetadata

编译器给了我一个警告

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

columndMetadata
内部创建方法是否更好,比如
getStreamMetadata
getFileMetadata
getSocketMetadata
。或者将
ColumnDBMetadata
传递给创建正确接口的工厂?

有一种气味。。。列如何实现流、文件和套接字?看起来,它可能是这些类的消费者,但不是天生的

混淆了,你的基本流<代码>接口<代码>(我明白它是C++的一个接口而不是真正的一个接口!),它没有公开足够的通用功能来帮助它。文件和套接字接口实现不同的语义。您需要一个更通用的接口,该接口由文件/套接字实现,然后只需将基本接口传递给

columndMetadata
的构造函数,它就可以随心所欲地使用它,因为您已经混淆了实现

也可以考虑将此添加到基本接口类:

C4584: 'ColumnDBMetadata' : base-class 'IStreamMetadata' is already a base-class of 'IFileMetadata'.

是的,这是个糟糕的设计。大多数人都会理解这个
类ColumnDBMetadata:public IStreamMetadata、public IFileMetadata、public ISocketMetadata
意味着
ColumnDBMetadata
的实例是所有3个实例同时出现

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


另一种方法是反转您提出的层次结构:使DB类基类接口,并让套接字、流和文件元数据继承它。因此,您将首先创建DB类(通过工厂),确定它是什么,然后将其向下转换为一种特殊类型。

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

您的继承应该如下所示:

virtual ~IStreamMetaData() = 0 { };
virtual关键字的作用是将所有重复继承的函数定义融合在一起。如果您不这样做,编译器会认为您继承了同名的不同函数,这就是您收到该警告的原因

基本上,您应该养成一种习惯,始终将纯虚拟的“接口”类继承为

公共虚拟机


此外,您还需要在所有这些接口类中编写一个空的内联虚拟析构函数,因为即使该类不做任何事情,该语言也希望有一个虚拟析构函数



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

我发现包含“数据”、“信息”、“管理器”的类很奇怪,以及类似的后缀。流需要的所有数据(理论上)都包含(甚至可能隐藏)在类中。每次我想上这样的课时,我都会问自己:我为什么要这样做?一定还有别的办法。在不知道这些类的上下文的情况下,这将是我改进设计的一个问题


然后定义许多getter。我并不是说获得者一般都是邪恶的。在SO(搜索getter和setter)上有一些关于这个主题的很好的讨论。对我来说,getters再次暗示,有些事情可以做得更好。一个能干的人说:我不知道怎么做,所以在这里拿东西,自己做。有时我会接受这种情况,有时我会为此找到更好的设计。

查阅diamond Inheritation,你会很快找到一些缺失的好解释。首先,确保你问自己“是a”或“有a”。另外,我会避免使用以
I
开头的
类。使它看起来像一个
接口
。如果
文件
是一个
,那么将这两个文件都保存有什么意义呢?@crashmstr:这是一个接口。我忘记了实现析构函数,这看起来像java,不是C++。有很多能手和能手,还有深厚的继承力。如果你不是在寻找多态性,为什么要用它来代替模板呢?单个setter真的有用吗,还是应该改为构造函数参数?或者我们正在查看原始数据存储(在这种情况下,您应该使用
struct
,直接访问元素,而不是通过函数调用)?该列只包含有关这些接口的信息。columnDBMetadata只是一个检索信息的对象。从数据库中,我想说的是,它可能会使用各种流,但不会继承,因为它本身不是流。请看Crashstr关于“是a”和“有a”的评论。我忘记了做这件事,就像我上面提到的那样。
class IFileMetadata: public virtual StreamMetadata

class ISocketMetadata: public virtual IStreamMetadata

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