繁体   English   中英

使用std :: move以防止复制

[英]using std::move to prevent copying

我有以下代码:

#include <iostream>
#include <vector>

struct A
{
    std::vector<int> x;

    A()
    {
        std::cout << "A()" << std::endl;
    }

    A(const A&)
    {
        std::cout << "A(const A&)" << std::endl;
    }

    ~A()
    {
        std::cout << "~A()" << std::endl;
    }
};

struct B : public A
{
    std::vector<int> y;

    B()
    {
        std::cout << "B()" << std::endl;
    }

    B(const A&a)
    {
        std::cout << "B(const A&)" << std::endl;
        x = std::move(a.x);
        y.resize(x.size());
    }

    B(const A&&a)
    {
        std::cout << "B(const A&&)" << std::endl;
        x = std::move(a.x);
        y.resize(x.size());
    }
    B(const B&)
    {
        std::cout << "B(const B&)" << std::endl;
    }

    ~B()
    {
        std::cout << "~B()" << std::endl;
    }
};

A ret_a()
{
    A a;
    a.x.resize(10);
    return a;
}

int main()
{
    std::cout << "section I" << std::endl << std::endl;

    A a = ret_a();  
    B b(a);
    std::cout << "a.x.size=" << a.x.size() << std::endl;

    std::cout << std::endl << "section II" << std::endl << std::endl;

    B b2(ret_a());
    std::cout << "b.x.size=" << b.x.size() << std::endl;

    std::cout << std::endl << "section III" << std::endl << std::endl;
    return 0;
}

带输出(VS2013,发布版本)

section I

A()
A()
B(const A&)
a.x.size=10

section II

A()
A()
B(const A&&)
~A()
b.x.size=10

section III

~B()
~A()
~B()
~A()
~A()
  1. 为什么“ I部分”中的axsize()的大小为10? 我认为std :: move应该将所有数据从ax移到yx

  2. 为什么“第二节”两次调用构造函数A()? 我认为B(const A &&)可以防止A的过度复制

UPDATE

请参阅http://pastebin.com/70Nmt9sT上的固定代码

  1. T&&const T&&不是同一类型。 您几乎永远不需要const rvalue引用-自从将其const后就无法窃取其资源! x = std::move(ax); B(const A&a) const vector<int>&&复制ax因为std::move(ax)的返回类型是const vector<int>&&
  2. 构造函数, B(const A&&)调用的默认构造A因为它是衍生自A ,和成员初始化列表不会使试图构造基A 这是第二个A呼叫。

为什么“ I部分”中的axsize()大小为10? 我认为std::move应该将所有数据从ax移到yx

这是因为B(const A&& a) 由于a是该构造const ,因此您只能对其成员x进行const访问,并且在vector<T> const上调用std::move导致vector<T> const&&不能绑定到vector的move构造函数(采用vector<T>&&参数)。 相反,它最终调用了复制构造函数,这使源对象保持不变。

为什么“第二节”两次调用构造函数A() 我认为B(const A&&)可以防止A过度复制

第一个默认构造发生在ret_a()的主体内。 第二种默认构造是BA子对象的构造。 为了避免第二步,在成员初始化器列表中move A实例。

B(const A&&a)
: A(std::move(a))
{
    std::cout << "B(const A&&)" << std::endl;
    y.resize(x.size());
}

需要注意的是, move实际上并没有导致的内容移动a因同样的原因如上所述。 此外,即使修改签名B(A&& a)不会导致内容a移动由于用户提供拷贝构造函数和析构函数的定义,防止转移构造的隐代A ,它会被复制而不是。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM