封装矢量

时间:2011-11-28 22:55:12

标签: c++ vector encapsulation

以下是我班级的一小部分样本:

#include <string>
#include <vector>

using std::string;
using std::vector;

struct Book {
  string m_author;
  string m_title;
};

class BookList
{
public:
  BookList();
  ~BookList();

private:
  vector<Book*> m_books;
}

如您所见,BookList的数据以vector Book的形式存储。编写访问器的最佳方法是什么?我是否应该允许用户通过HasMore()&amp; GetNextBook()方法,或者只返回整个向量会更好吗?或者也许是迭代器?

提前致谢。

5 个答案:

答案 0 :(得分:1)

如果您没有在课程中添加任何其他功能,您可以考虑使用typedef代替:

typedef vector<Book*> BookList;

如果要添加其他功能,则公开迭代器begin()end(),类似于STL容器和修改方法。

答案 1 :(得分:1)

首先,您可能不需要存储指针。请改用值。在这里你有三个选项之一,真的:

  1. 按值或按引用返回向量。
  2. 公开开始/结束迭代器。
  3. 只需将矢量公开,或完全删除BookList,然后直接使用std::vector<Book>
  4. GetNextBook方法很糟糕,因为它使你的列表存储迭代状态没有充分的理由。并且也让你成为唯一一个这样做的人。

答案 2 :(得分:0)

返回对向量或迭代器对的引用。以非标准方式编写访问器/重新实现迭代器接口是没有意义的。 另一个有用的选项是从STL容器派生您的类。

答案 3 :(得分:0)

最终,你想让它尽可能抽象,至少对任何公众都是如此。有几点需要考虑:

  • 如果你返回整个事物,你就有可能让公众能够修改矢量。你真的希望他们能够做到吗?
  • 如果您需要在某个时候更改班级的布局怎么办?如果您编写自己的方法来返回所需的数据,那么它允许您在将来的某个时候交换vector而不会破坏与其他所有内容的兼容性。
  • 返回整个向量将生成大量堆栈帧。你需要理想地传递一个指针。

如果您可能不需要更改实现,则返回迭代器可能会有效。

答案 4 :(得分:0)

正如其他人所提到的,如果BookList没有其他责任,删除typedef类并将其替换为适当的BookList可能是最佳选择。但是,如果需要BookList,那么提供m_books访问权限的一些选项将是:

  • 返回vector< Book* > const &
  • 的方法
  • 一对begin / end方法,它们返回多态迭代器包装器,例如thisthis

第一个选项是最简单的但是将内部数据布局暴露给客户端。第二个选项允许您替换底层容器而无需对客户端进行任何更改。由您来决定哪种最适合您的设计。

此外,如果vector< Book* >不是多态基类,您可能需要考虑将vector< Book >替换为Book。如果是,那么智能指针的容器可能是更好的选择。