C++;STL数据结构与Java的比较 我目前正在学习C++,试图适应它所带来的标准数据结构,但它们看起来都很裸露。例如,list并没有像我在Java中习惯的get(索引)这样的简单访问器。像pop_back和pop_front这样的方法也不会返回列表中的对象。所以你必须做一些类似的事情: Object blah = myList.back(); myList.pop_back(); class X { // ... }; // ... X x;

C++;STL数据结构与Java的比较 我目前正在学习C++,试图适应它所带来的标准数据结构,但它们看起来都很裸露。例如,list并没有像我在Java中习惯的get(索引)这样的简单访问器。像pop_back和pop_front这样的方法也不会返回列表中的对象。所以你必须做一些类似的事情: Object blah = myList.back(); myList.pop_back(); class X { // ... }; // ... X x;,java,c++,Java,C++,而不是像这样简单的事情: Object blah=myList.pop_back() 在Java中,几乎每个数据结构都返回对象,因此不必进行这些额外的调用。为什么C++的STL容器是这样设计的?在java中,我做的普通操作不是C++常见的吗? 编辑:对不起,我想我的问题的措辞很糟糕,因为我得到了所有的反对票,但肯定有人可以编辑它。为了澄清,我想知道为什么STL数据结构与Java相比是这样创建的。还是我一开始使用了错误的数据结构?我的观点是,这些看起来像是(在我的示例中)在列表上使用的常见操作,当

而不是像这样简单的事情:
Object blah=myList.pop_back()

在Java中,几乎每个数据结构都返回对象,因此不必进行这些额外的调用。为什么C++的STL容器是这样设计的?在java中,我做的普通操作不是C++常见的吗? 编辑:对不起,我想我的问题的措辞很糟糕,因为我得到了所有的反对票,但肯定有人可以编辑它。为了澄清,我想知道为什么STL数据结构与Java相比是这样创建的。还是我一开始使用了错误的数据结构?我的观点是,这些看起来像是(在我的示例中)在列表上使用的常见操作,当然每个人都不希望每次都编写自己的实现

编辑:将问题改写为更清楚。

关于
pop()
类函数,至少有两件事需要考虑:

1) 对于返回的
pop_-back()
pop_-front()
无需返回的情况,没有明确和安全的操作

2) 这些函数将按值返回。如果在容器中存储的类型的复制构造函数中引发异常,则该项将从容器中删除并丢失。我想这被认为是不受欢迎和不安全的

关于访问列表,标准库的一般设计原则是不避免提供低效的操作
std::list
是一个双链接列表,通过索引访问列表元素意味着从开始或结束遍历列表,直到到达所需位置。如果您想这样做,您可以提供自己的助手函数。但是如果您需要随机访问元素,那么您可能应该使用列表以外的结构。

back()
返回对向量的最后一个元素的引用,这使得它几乎可以自由调用
pop_back()
调用向量最后一个元素的析构函数

显然,
pop_back()
无法返回对已销毁元素的引用。因此,要使语法正常工作,
pop_back()
必须在销毁元素之前返回元素的副本

现在,如果你不想要那份拷贝,我们只是不必要地复制了一份

< C++标准容器的目标是给你提供几乎是裸露的金属性能,包在漂亮的,易于使用的敷料中。在大多数情况下,它们不会为了易用性而牺牲性能,而返回最后一个元素副本的
pop_back()
会为了易用性而牺牲性能

可能会有一个pop-and-get-back方法,但它会复制其他功能。而且在很多情况下,它的效率要比“回来”和“砰砰”低

作为具体的例子,

vector<foo> vec; // with some data in it
foo f = std::move( vec.back() ); // tells the compiler that the copy in vec is going away
vec.pop_back(); // removes the last element
向量向量向量里面有一些数据 foo f=std::move(vec.back());//告诉编译器vec中的副本将消失 vec.pop_back();//删除最后一个元素
请注意,移动必须在元素销毁之前完成,以避免创建额外的临时副本
pop_back_和_get_value()
必须在元素返回之前销毁它,而赋值将在元素返回之后进行,这是浪费

列表甚至没有像get(index)这样的简单访问器

为什么要这样做?一种允许你从列表中访问第n个元素的方法,可以隐藏操作的<代码> o(n)< />代码的复杂性,这就是C++不提供它的原因。出于同样的原因,C++的
std::vector
不提供
pop_front()
函数,因为该函数在向量大小上也是
O(N)

像pop_back和pop_front这样的方法也不会返回列表中的对象

也可以,因为C++具有自由函数,所以不难将其扩展到 STD::List或任何标准容器的操作。

template<class Cont>
typename Cont::value_type return_pop_back(Cont& c){
  typename Cont::value_type v = c.back();
  c.pop_back();
  return v;
}
模板
typename Cont::value\u type return\u pop\u back(Cont&c){
typename Cont::value_type v=c.back();
c、 向后弹出();
返回v;
}
但是,应该注意的是,上述函数不是异常安全的,这意味着如果
返回v抛出,您将有一个已更改的容器和一个丢失的对象。

列表没有get(index)方法,因为按索引访问链接列表效率非常低。STL的理念是只提供一些可以有效实现的方法。若您希望在效率低下的情况下通过索引访问列表,那个么您可以很容易地自己实现

pop_back不返回副本的原因是返回值的副本构造函数将在函数返回后调用(不包括RVO/NRVO)。如果此复制构造函数引发异常,则表示您已从列表中删除该项,但未正确返回副本。这意味着该方法不是异常安全的。通过分离这两个操作,STL鼓励以异常安全的方式进行编程

为什么C++的STL容器是这样设计的? 我认为比亚恩·斯特劳斯图普:

C++既精干又吝啬。基本原则是你不付钱 为了你不用的东西

在返回该项的<代码> POP())/Cux>方法的情况下,考虑到为了既删除该项又返回该项,该项不能通过引用返回。引用对象不再存在,因为它只是
pop()
ed。它可以通过指针返回,但前提是