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_Interface - Fatal编程技术网

C++ 类接口:基本还是复杂?

C++ 类接口:基本还是复杂?,c++,oop,interface,C++,Oop,Interface,我写了一个容器类的乐趣和教育。以前在编写容器类时,我只使用了几个非常基本的方法:GetValue、SetValue、GetSize和Resize。我这样做是为了避免“代码意大利面”,这样我的类就更容易调试 然而,我突然想到,该类的用户可能希望做的不仅仅是简单的替换。因此,我又添加了一些方法: void Replace(const std::size_t Start, const std::size_t End, const T Value); void Replace(const std::si

我写了一个容器类的乐趣和教育。以前在编写容器类时,我只使用了几个非常基本的方法:
GetValue
SetValue
GetSize
Resize
。我这样做是为了避免“代码意大利面”,这样我的类就更容易调试

然而,我突然想到,该类的用户可能希望做的不仅仅是简单的替换。因此,我又添加了一些方法:

void Replace(const std::size_t Start, const std::size_t End, const T Value);
void Replace(const std::size_t Start, const std::size_t End, const MyClass Other);
void Insert(const std::size_t Index, const T Value);
void Insert(const std::size_t Index, const MyClass Other);
void Delete(const std::size_t Index);
void Delete(const std::size_t Start, const std::size_t End);

一般来说,类是否应该只提供最基本的接口,让类的用户自己创建函数来完成复杂的工作?还是应该以可维护性为代价内置复杂的内容?

如果此容器仅由您在代码中使用,并且您的接口方法足以用于特定目的,则可以这样做


但是,一旦其他人要使用该容器,或者您计划在其他领域使用它,我建议添加使用迭代器类型的接口方法,那么您的容器将更加开放,可以与stdlib容器和算法一起使用。以stdlib容器的接口为例。

我有类似的例子。我的建议是,您有两个“基类”或“超级类”

第一个类是非常通用的类,表示所有容器类的“概念根”,几乎不是方法,类似于接口,应该如下所示:


1.hpp
第二节课,开始变得不那么概念化,更“真实世界”:


mcontainers.hpp } 最后,还有一些具体的类别:


6.hpp
正如@Chris提到的,有几个库可以实现这一点,但这条规则总是有一个例外,如果需要的话,你可能想“重新发明轮子”

我有一个应用程序,它有一组库,其中包括一些容器/集合。它是在另一个节目中制作的。兰格。并需要它迁移到C++。 AltEube,我还检查C++标准库,我结束了我的库迁移到C++,因为我有几个库调用我的容器库,需要它快速地完成。 在使用“基类”时,您可能希望在子类中“保护”其成员并“公开”。我通常不创建“私有”字段或方法,除非必要


摘要:一些非常常见的复杂内容(如内存分配或存储)可以在基类中完成,但这些复杂性中的大部分应该留给子类来完成。类应该只提供成员函数的基本/最小接口(最好没有数据!)。然后,您可以添加方便的方法,如非好友非成员函数。然而,根据接口原理,这些函数仍然是类接口的一部分

您已经指出了主要原因:它使类更易于维护。此外,实现“方便性”方法部分将作为一个很好的测试,看看您的接口是否足够好

注意,容器的成员函数部分通常应该是非常通用和强大的,并且只关心维护类不变量


据我所知,这是关于这个问题的最现代的观点。Scott Meyer的“有效的C++”(在最近的第三版)以及Sutter和Alexandrescu的“C++编码标准”中都大力提倡这一点。

问题是,一旦您编写了另一个容器类(在野外有很多容器类,您可能需要不同的类型),您就会发现您的设计是O(N*M)中的正方形,其中N是容器类的数量,M是算法的数量

解决方案是将容器与算法解耦,这就是为什么在STL中引入迭代器

迭代器还有其他选择,例如使用多态性。您可以在抽象的公共基类中分解出遍历接口,并根据它实现算法


简而言之,不要使用容器类中的大部分逻辑。

您应该尽量精简接口,特别是如果您可能希望实现不同的容器类型,例如基于数组和链表。如果在所有容器中提供一些基本方法,则可以创建执行某些任务但可以在所有容器上工作的外部算法:

 void Replace(const std::size_t Start, const std::size_t End, const T Value);
可能成为

 template<class ContainerType>
 void ReplaceAllElementsInContainer(ContainerType& Container, const std::size_t Start, const std::size_t End, const T Value);
模板
void replacementsincontainer(ContainerType&Container,const std::size\u t Start,const std::size\u t End,const t Value);
课外活动。如果不这样做,就必须在所有容器中编写所有这些方法


另一种可能是使用模板方法模式(与C++模板无关),并将所有这些方法写入基类(它定义了基本方法为纯虚的,并从实现的“便利”方法调用它们)。这可能会导致许多虚拟函数调用,但出于性能原因,容器类中可能不需要这些调用。

首先,您需要这些函数吗?第二,如果你让它遵循标准的库模式,你的生活就会变得更轻松。@Chris我的目的是教育和娱乐,所以可能是,也可能不是。两种不同的插入和替换方法有什么不同?T vs MyClass.@mlaw
Insert
将其他元素推到一边,为新元素腾出空间<代码>替换只是覆盖它们。容器类是模板化的,因此
T
表示类存储的内容,
MyClass
表示类本身。知道了。所以Insert(Index,MyClass-Other)就像一个“addAll”操作。
#include "containers.hpp";
#include "mcontainers.hpp";

#define pointer void*

class Stack: public MethodContainer
{
public:
  // these methods use "mcontainer::Insert", "mcontainer::Replace", etc
  void Push(pointer Item);
  void Pop();
  pointer Extract();
}
 void Replace(const std::size_t Start, const std::size_t End, const T Value);
 template<class ContainerType>
 void ReplaceAllElementsInContainer(ContainerType& Container, const std::size_t Start, const std::size_t End, const T Value);