为vector做临时变量?

时间:2016-04-05 14:51:23

标签: c++

以下哪项更好? vector<vertex>vertices.push_back(new vertex); vertices[vertices.size()-1].name = name;

vertex v
v.name = name;
vertices.push_back(v);

{{1}}

我认为第一个更好,因为它不进行任何额外的复制,但第二个更具可读性,所以我不确定。

4 个答案:

答案 0 :(得分:2)

坏(和.push_back(new vertex))都特别糟糕(并且它不能用于std::vector<vertex>,因为它会返回指针)。

你得到了什么:

vertices.push_back(vertex());             // construct temporary object
                                          // copy it to vector
                                          // destroy temporary object
vertices[vertices.size()-1].name = name;

VS

vertex v;                                 // construct temporary
v.name = name;                               
vertices.push_back(v);                    // copy temporary object with a string

假设复制字符串不便宜,第二种选择更糟糕。但是,如果您的编译器决定对第一种情况应用Copy elision优化(由于vertex()是无名的临时情况,它有资格执行),则不会引入临时对象。

C ++ 11附带的清洁解决方案允许直接在向量的内存中构造对象而不使用临时对象

vectices.emplace_back(/* vertex ctor parameters */);  // no temp objects here
vertices.last().name = name;

答案 1 :(得分:0)

选项一将在堆上分配顶点,而选项二将在堆栈上本地分配顶点。

这实际上取决于您的用例,我们需要更多的上下文。

答案 2 :(得分:0)

这两者并不完全可比。在(1)中,您正在堆上创建一个对象,而另一个正在堆栈上创建并复制到向量(所以是的,您正在制作2个副本)。真的取决于你的要求和背景。

(1)由于堆分配肯定会花费更多时间,但它是一个更持久的对象。

答案 3 :(得分:0)

使用vector :: emplace_back(Args ...)方法,避免任何不必要的副本。 如果存在一个顶点的构造函数,它接受一个名称的某种类型的字符串参数,那将是理想的。如果它不存在,我强烈建议为此添加一个,因为添加一个具有特定名称的新顶点似乎是一个常见的操作。

vector.emplace_back(...,"My Name",...);

如果不存在这样的构造函数,我将使用您列出的第二种方法。使用像MyVector.push_back(new element)这样的新内容时,您必须记住删除它。最重要的是,如果在构造对象时抛出异常,它们可能会发生内存泄漏。如果你真的需要使用&#34; new&#34;方法考虑使用适当的智能指针。