【发布时间】:2011-09-09 11:55:30
【问题描述】:
c++中的序列容器和容器适配器有什么区别?
这里我的意思是序列容器作为向量、双端队列、列表,而容器适配器作为堆栈、队列、priority_queue。 我们什么时候更喜欢序列容器和容器适配器?
【问题讨论】:
标签: c++ stl containers
c++中的序列容器和容器适配器有什么区别?
这里我的意思是序列容器作为向量、双端队列、列表,而容器适配器作为堆栈、队列、priority_queue。 我们什么时候更喜欢序列容器和容器适配器?
【问题讨论】:
标签: c++ stl containers
容器适配器使用包含来提供有限对序列容器功能的访问。许多容器适配器的公共方法只是对这个非公共元素的调用的包装器。如果您的应用程序可以使用容器适配器的有限功能,那么最好使用容器适配器。
假设您只是直接使用其中一个序列容器来实现一个队列。您调用 push_front 添加到队列中,调用 pop_back 从中删除。现在出现了一些 bozo 维护者并调用 pop_front 而不是 pop_back。如果您不希望有人弹出您打算用作队列或堆栈的事物的错误端,请不要提供该功能。容器适配器故意不提供对底层序列容器的完全访问。
另一方面,如果您需要深入了解(例如,您需要查看堆栈中的第二个元素),您将需要使用序列容器而不是适配器。您可能想考虑使用适配器理念:不要导出容器的全部功能。只需导出真正需要的功能。
【讨论】:
序列是一种特殊的容器,其中元素的顺序与它们的值无关。相反,它是它们附加到容器(或插入等)的顺序。
容器适配器根本不是容器,因为它不实现容器的接口(不提供迭代器等)。相反,它提供对容器的有限访问。标准库中提供的那些使用序列进行操作。
当您希望有限地访问对象集合时,您可以使用容器适配器。堆栈和队列都只允许您在一端添加。此外,堆栈仅允许您在写入的同一端读取/删除,而队列仅允许您在另一端读取/删除。他们不会做任何序列尚未做的事情,除了用于阻止您迭代所有元素等等。
priority_queue 的行为有点复杂,它确实添加了不属于序列的行为。
【讨论】:
您可以将序列容器视为“从头开始构建”的容器。他们使用不同的结构来保存数据,并有不同的算法时间来插入、删除和检索元素。
你可以找到很多关于容器算法时间的信息here
容器适配器是在序列容器上添加的行为,使它们尊重不同的范例。添加的行为可以是更严格的行为(堆栈只允许您在其上弹出/推送项目,不允许随机插入)。它们是其他类型的容器,不需要新的存储行为,而不是已经存在的容器。例如,堆栈可以建立在向量之上。然后它会使用vector的数据结构,但限制使用特定的一组函数来模拟堆栈。
最重要的是确保您使用正确的容器来满足您的需求。更严格的容器将帮助您防止数据的误用,了解数据的使用情况将帮助您选择好的容器以获得最佳性能。
有关容器适配器的更多信息可以找到here
许多专家(Scott Meyer、Bjarne Stroustrup)建议默认使用vector,而其他专家(如Steve Jessop 指出的Herb Sutter)建议使用deque。我强烈建议您选择最适合您需要的容器。
【讨论】:
deque(gotw.ca/gotw/054.htm),或者至少在几年前就这样做了。
deque、list 或vector 来表示stack。这三个都工作正常。 gcc 使用deque。
当你需要一个栈时你应该使用栈容器适配器,当你需要一个队列时你应该使用队列适配器,当你需要一个优先级队列时你应该使用priority_queue适配器。
如果您不确定何时需要这些:堆栈在一端增长和缩小,因此您可以将其用作累加器来存储中间结果(堆栈机器);使用队列以先进先出 (FIFO) 的方式处理事物;优先级队列按定义的顺序弹出元素(例如,存储任务,然后按重要性顺序检索它们)。
【讨论】: