vector与非成员函数的类(以及类型定义)

Class of std::vector vs non-member functions (along with a typedef)

本文关键字:类型 定义 成员 函数 vector      更新时间:2023-10-16

在我的项目中有以下设计困境:
我有一个我设计的类的对象存储在一个std::vector中。我想为这类向量(std::vector<MyClass>)添加一些方法。我正在考虑将这个向量封装在另一个类中,并添加我需要的这些方法,当然也提供了我使用的std::vector的所有功能。这是个明智的主意吗?或者我应该使用非成员函数,或者为了我自己的方便使用typedef ?

非成员函数在这种情况下是正确的。请参阅Scott Meyer关于非成员函数如何改进封装的文章。

同样,请使用typedef std::vector<MyClass> someTypeName;,你不希望std::vector<MyClass>在你的代码中到处都是。你需要的是类型是什么而不是它是如何实现的。如果您必须更改实现以使用不同的容器,那么您会很高兴使用了typedef。

ETA:在评论中我想起了using及其相对于typedef的优越性。

using someTypeName = std::vector<MyClass>; 

只有当你的类型确实是一个向量时,你才应该使用typedef。typedef几乎不能控制你自己的类型的行为和你可以用它做什么。

如果没有,如果你想要一个合适的长寿设计,那么你应该隐藏实现细节:

  • 如果明天你使用另一种标准容器,如列表或地图呢?
  • 如果你的需求发生变化,你需要一些非标准的结构,如concurrent_vectors甚至是数据库,该怎么办?
  • 如果在插入或其他矢量操作中,你决定做一些额外的步骤。

有两种方法:

  • 拥有一个vector成员,并且只发布你真正需要的方法(根据组合而不是继承的原则)
  • 继承了标准的向量,但是同样,只有当你的类型表示一个向量结构,并且你意识到限制(例如缺少虚析构函数等)和它们的后果。

如果我理解正确,您想要有一个自定义容器,提供std::vector成员函数和特定于该容器的自定义函数?

在我看来,最适合你的方法是创建你自己的类型并封装你的vector:

class MyClass{};
class MyContainer {
  using size_type = std::vector<MyClass>::size_type;
public:
  MyContainer() = default;
  MyContainer(std::vector<MyClass> const& vec) : vec_(vec) {}
  size_type size() const noexcept;
  // other functions you want
private:
  std::vector<MyClass> vec_;
};

其他"坏"选项:

  • 创建非成员函数,但不适合OOP设计
  • 继承自std::vector,但STL类不是为继承