【问题标题】:vector push back clarifying矢量推回澄清
【发布时间】:2016-08-22 10:40:17
【问题描述】:

我无法弄清楚 push_back(const value_type& val) 究竟是如何工作的,在 docs 中它说的是 val

val is Value to be copied (or moved) to the new element ...

  1. 引用val时如何复制?

  2. 复制会调用val 的复制构造函数吗?

这里到底发生了什么?

#include <iostream>
#include <vector>    
using namespace std;    
struct x
{
    x(int v = 0) : v(v) {}
    int v;
};    
vector<vector<x>> parts;    
void fillParts()
{
    vector<x> values = { x(1), x(2), x(3) };
    parts.push_back(values);
}        
int main()
{
    fillParts();  
    parts[0][0].v = -123;
    cout << parts[0][0].v;    // -123
    return 0;
}

这运行没有错误, parts[0] 是对局部向量 values 的引用还是副本? 如果它是一个引用,它至少不应该给出一些警告,说明您访问和修改已释放堆栈的本地对象吗?

【问题讨论】:

  • 使用复制构造函数复制值,parts 向量在执行push_back 时复制values 向量,因此在访问它们时它们不会被释放。局部变量values 确实被释放了,但是具有相同底层数据的复制向量存储在“parts”中。
  • @JavierMr 是的,但 push_back 引用 - 那么它如何执行 values 向量的复制?
  • @ampawd 为什么不呢? Copy Constructor 通常采用引用方式,它可以完美地执行复制。
  • 我认为编译器可能会优化代码以使用void push_back (value_type&amp;&amp; val);,并且您将使用移动赋值运算符。无论如何,它将是复制或移动的实体。其实,你可以用 F11 调试它。
  • @Yola 嗯,听起来很有趣,但移动是 c++11 的特性,在以前的标准中它不会这样做

标签: c++ visual-c++ stl push-back


【解决方案1】:

通过引用获取val时如何复制?

想想一个复制构造函数。 它通过引用获取参数,并且完美地执行复制。

class Bar
{
public:
    Bar(const Bar & rhs); // by reference, to copy.
};

复制会调用 val 的复制构造函数吗?

复制操作使用复制构造函数。

您实际上可以通过提供用户定义的构造函数来查看它是否被复制或移动。

struct x
{
public:
    x(const x & rhs)
    {
        // Some copy operation.
        std::cout << "Copied" << std::endl;
    }

    x(x && rhs)
    {
        // Some move operation.
        std::cout << "Moved" << std::endl;
    }
};

【讨论】:

  • 注意:对于问题中的struct x,您需要在这些构造函数中实际执行成员变量的复制!
  • is vector 复制构造函数看起来像这样 vector&lt;T&gt;(const vector&lt;T&gt;&amp; rhs) ?
  • @ampawd 您在xstd::vector 的构造函数之间感到困惑。现在,您正在查看此复制操作的另一(或错误)方面。你打电话给push_back,(不是构造函数)
  • @DeanSeo 不,我实际上明白了你的意思,......只是为了澄清一些事情
  • @DeanSeo 并且在我的示例中也将调用向量的复制 ctor,因为 parts[0] 是向量
【解决方案2】:

你可以试试这个

class A
{
public:
    A() {}
    A(const A&) { cout << "copy cons" << endl; }
    A& operator= (A &&) { cout << "move" << endl; };
    A& operator= (const A &) { cout << "copy" << endl; };
};
vector<A> parts;
void fillParts()
{
    A a;
    parts.push_back(a);
}
int main()
{
    fillParts();
    return 0;
}

我在调试和发布版本中都调用了复制缺点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-14
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多