c++ 中集合/容器的接口/超类
我来自 Java 世界,目前正在构建一个小型 C++ 程序。 我有一个对象,它执行一些工作,然后将工作结果作为列表返回。
一天后,我更改了对象的行为,将结果保存在一组中,以避免容器中出现重复。 但我不能简单地返回集合,因为我第一次使用了接口的列表。 是否有一个通用的容器接口,我可以使用它来指定对象的接口,而忘记我在内部使用的容器类型?
目前,我正在创建一个集合,添加所有值,然后从该集合创建一个列表:
return std::list<foo>(this->mySet.begin(), this->mySet.end())
似乎有点奇怪。
I'm coming from the Java world and are building a small c++ program at the moment.
I have an object that does some work and then returns the result of the work as a list.
Now a day later i changed the behavior of the object to save the results in a set to avoid duplicates in the container. But I can't simply return the set because I used a list for the interface in the first time.
Is there a common container interface that I can use to specify the interface of my object and forget about the container type I use internally?
At the moment I'm creating a set adding all the values and then creating a list from the set:
return std::list<foo>(this->mySet.begin(), this->mySet.end())
Seems a little strange.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
容器的概念是由迭代器体现的。
正如您所看到的,对特定类型的容器进行硬编码可能不是您想要的。 所以让你的类返回迭代器。 然后您可以重新使用容器迭代器。
现在,当您将容器类型从 std::list 更改为 std::set 时,没有人需要知道。
另外,通过使用其他容器使用的标准名称,您的类开始看起来像 STL 中的任何其他容器。
注意:返回 const_iterator 的方法应该是 const 方法。
The concept of a container is enbodied by iterators.
As you have seen hard coding a specific type of container is probably not what you want. So make your class return iterators. You can then re-use the conatiners iterators.
Now when you change the Container type from std::list to std::set nobody needs to know.
Also by using the standard names that other containers use your class starts to look like any other container from the STL.
Note: A method that returns a const_iterator should be a const method.
整个 C++ 标准库(包括其容器)与 Java 不同,不是接口(继承、多态性),而是基于模板(为了提高效率)。
您可以围绕您的集合创建一个多态包装器,但这不是 C++ 方式。
最简单的解决方案就是使用一些类型别名来简化程序:
您现在可以更改
Collection
-typedef,而无需更改任何其他内容。 (注意:如果您将Collection
公开,用户将能够引用您显式使用的类型)The whole C++- standard library including its containers is - unlike Java - not interface (inheritance, polymorphism)- but template-based (for the sake of efficiency).
You could create a polymorphic wrapper around your collection but this isn't the C++-way.
The simplest solution is just to simplify the programm with some type aliases:
You can now change the
Collection
-typedef without having to change anything else. (Note: If you makeCollection
public, the user will be able to refer the the type you used explicitly)不存在任何接口。 相反,您通常会使用模板,并简单地说“我不在乎它是什么类型,只要它表现为容器即可”。
假设您的函数如下所示:
它可以这样调用:
如果您决定返回
set
,则只需更改第一个函数。 调用函数并不真正关心(当然,只要您不依赖列表的细节)。如果您发布更多示例代码,我们可能能够更好地建议如何在 C++ 中完成它。
No interface exists. Instead, you would typically use templates, and simply say "I don't care what type it is, as long as it behaves as a container".
Assuming your function looks like this:
it can be called like this:
Only the first function has to be changed if you decide to return a
set
instead. The calling function doesn't really care (as long as you don't rely on the specifics of a list, of course).If you post a bit more sample code, we might be better able to suggest how it should be done in C++.
根据您的描述,我认为简短的答案是否定的。
一般来说,当我创建某种形式的像这样的集合时,我通常会使用 typedef 来指定我正在使用的容器:
所有客户端代码均引用“Object::Cont”等,因此只要客户端仅使用容器的一般特性,如果容器发生变化,它们不需要改变。
如果你现在不能改变你的API,那么我认为你的解决方案非常好,但是,根据你拥有的数据,如果你做了很多往往是唯一的插入,那么继续使用可能会更有效列出并仅删除末尾的重复项:
From your description I think the short answer is no.
In general when I'm creating some form of collection like this I would normally use a typedef to specify the container that I'm using:
All client code refers to "Object::Cont" etc. and so as long as clients only use the general features of containers, they will not need to change if the container changes.
If you cannot change your API now, then I think your solution is pretty good, however, depending on the data that you have, if you do a lot of inserts that tend to be unique, then it may be more efficient to continue using the list and only remove duplicates at the end: