封装向量

发布于 2024-12-18 06:29:57 字数 490 浏览 0 评论 0原文

这是我的课程的一个小示例:

#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 的数据以 Book向量 的形式存储。编写访问器的最佳方法是什么?我是否应该允许用户通过 HasMore() & 来一一检索它们? GetNextBook() 方法,或者直接返回整个向量会更好吗?或者也许是一个迭代器?

提前致谢。

Here is a small sample of my class:

#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;
}

As you can see, the data for BookList is stored in the form of a vector of Books. What would be the best way to write an accessor? Should I allow the user to retrieve them one by one via HasMore() & GetNextBook() methods, or would it be better to just return the entire vector? Or perhaps an iterator?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

許願樹丅啲祈禱 2024-12-25 06:29:57

首先,您可能不需要存储指针。请改用一个值。在这里,您实际上有以下三个选项之一:

  1. 按值或按引用返回向量。
  2. 公开开始/结束迭代器。
  3. 只需将向量公开,或者完全摆脱 BookList,然后直接使用 std::vector 即可。

GetNextBook 方法很糟糕,因为它使您的列表无缘无故地存储迭代状态。并且也使您成为唯一这样做的人。

First of all, you probably don't need to store a pointer. Use a value instead. And here you have one of three options, really:

  1. Return a vector, by value or by reference.
  2. Expose begin/end iterators.
  3. Just make the vector public, or get rid of BookList altogether, and just use std::vector<Book> directly.

GetNextBook approach is bad, because it makes your list store iteration state for no good reason. And also makes you the only person who does that.

情魔剑神 2024-12-25 06:29:57

如果您不向类添加任何其他功能,您可以考虑仅使用 typedef:

typedef vector<Book*> BookList;

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

If you are not adding any additional features to the class you may consider just using a typedef instead:

typedef vector<Book*> BookList;

If you are adding additional features then expose iterators begin() and end(), similar to the STL containers, plus modification methods.

z祗昰~ 2024-12-25 06:29:57

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

Return reference to the vector or pair of iterators. Writing accessors / reimplementing iterators interface in a non-standard way is pointless.
Another option, useful sometimes, is to derive your class from an STL container.

慕烟庭风 2024-12-25 06:29:57

最终,您希望使其尽可能抽象,至少对于面向公众的任何内容而言是如此。有几件事需要考虑:

  • 如果您返回整个内容,则公众将面临修改向量的风险。您真的希望他们能够做到这一点吗?
  • 如果您需要在某个时候更改类的布局怎么办?如果您编写自己的方法来返回所需的数据,它允许您在将来的某个时刻交换向量,而不会破坏与其他所有内容的兼容性。
  • 返回整个向量将产生一个大量堆栈帧。理想情况下,您需要传递一个指针。

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

Ultimately, you want to make this as abstract as possible, at least to anything public-facing. There's a few things to think of:

  • If you return the whole thing, you risk the public being able to modify the vector. Do you really want them to be able to do that?
  • What if you need to change the layout of the class at some point? If you write your own methods to return the required data, it allows you to swap out the vector at some point in the future without killing compatibility with everything else.
  • Returning the whole vector will make a massive stack frame. You'd need to pass a pointer ideally.

If you probably won't need to change the implementation, returning an iterator could work.

当爱已成负担 2024-12-25 06:29:57

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

  • 返回 vector的方法。书*> const &
  • 一对 begin/end 方法,返回多态迭代器包装器,例如 这个this

第一个选项是最简单的,但向客户端公开内部数据布局。第二个选项允许您替换底层容器,而不需要对客户端进行任何更改。由您决定哪一个最适合您的设计。

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

As others have mentioned, removing the BookList class and replacing it with an appropriate typedef is probably the best option if BookList has no other responsibilities. If however, BookList is required then some options to provide access to m_books would be:

  • a method that returns a vector< Book* > const &
  • a pair of begin/end methods that return polymorphic iterator wrappers such as this or this

The first option is the simplest but exposes the internal data layout to clients. The second option would allow you to replace the underlying container without requiring any changes to clients. It's up to you to decide which is most appropriate for your design.

Also, you may want to consider replacing vector< Book* > with vector< Book > if Book will not be a polymorphic base class. If it is, then a container of smart pointers would probably be a better option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文