封装向量
这是我的课程的一个小示例:
#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 Book
s. 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,您可能不需要存储指针。请改用一个值。在这里,您实际上有以下三个选项之一:
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:
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.如果您不向类添加任何其他功能,您可以考虑仅使用 typedef:
如果您要添加其他功能,则公开迭代器
begin()
和end()
,类似于STL容器,加上修改方法。If you are not adding any additional features to the class you may consider just using a typedef instead:
If you are adding additional features then expose iterators
begin()
andend()
, similar to the STL containers, plus modification methods.返回对向量或迭代器对的引用。以非标准方式编写访问器/重新实现迭代器接口是没有意义的。
有时有用的另一个选择是从 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.
最终,您希望使其尽可能抽象,至少对于面向公众的任何内容而言是如此。有几件事需要考虑:
如果您可能不需要更改实现,则返回迭代器可能会起作用。
Ultimately, you want to make this as abstract as possible, at least to anything public-facing. There's a few things to think of:
vector
at some point in the future without killing compatibility with everything else.If you probably won't need to change the implementation, returning an iterator could work.
正如其他人所提到的,如果
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 appropriatetypedef
is probably the best option ifBookList
has no other responsibilities. If however,BookList
is required then some options to provide access tom_books
would be:vector< Book* > const &
begin
/end
methods that return polymorphic iterator wrappers such as this or thisThe 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* >
withvector< Book >
ifBook
will not be a polymorphic base class. If it is, then a container of smart pointers would probably be a better option.