首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用复制构造函数而不是移动构造函数

调用复制构造函数而不是移动构造函数
EN

Stack Overflow用户
提问于 2018-01-12 23:10:36
回答 2查看 986关注 0票数 1

我有以下类:

代码语言:javascript
复制
class Component {
  public:
    // Constructor
    explicit Component(const void* data, size_t size)
      : _size(size),
        _data(new int[_size]) {
          (void)memcpy(_data, data, _size);
    }

    // Destructor
    ~Component() {
      delete[] _data;
    }

    // Copy-ctor.
    Component(const Component& o)
      : _size(o._size),
        _data(new uint8_t[_size]) {
     (void)memcpy(_data, o._data, _size);
   }

   // Assignment operator
   Component& operator=(const Component& o) {
     if (this != &o) {
       delete[] _data;
       _size = o.getSize();
       _data = new uint8_t[_size];
       (void)memcpy(_data, o.getData(), _size);
     }
     return *this;
   }

   // Move-constructor
   Component(Component&& o)
     : _size(o._size),
       _data(o._data) {
     o._data = nullptr;
   }

   // Move assignment
   Component& operator=(Component&& o) {
     if (this != &o) {
       delete[] _data;
       _size = o._size;
       _data = o._data;
       o._data = nullptr;
     }
     return *this;
   }

   private:
    size_t _size;
    int _data;
};

我想测试一下我的移动构造函数。所以我试着这样做:

代码语言:javascript
复制
void f(Component&& c) {
  Component c2 = c; // Expect to use move-constructor
}
int data[] = { 0, 1 };
Component c{&data[0], sizeof(data)};
f(std::move(c)); // getting a rvalue reference from lvalue reference

但是后来我发现调用的是我的复制构造函数,而不是移动构造函数。你知道为什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-12 23:37:19

看起来您需要将f更改为

代码语言:javascript
复制
void f(Component&& c) {
    Component c2 = std::move(c);
}

然后这样叫它:

代码语言:javascript
复制
f(c);

请参阅:similar example

注意:我还没有测试过它,但请参阅另一个主题的答案以获得解释。

票数 1
EN

Stack Overflow用户

发布于 2018-01-12 23:48:09

在这段代码中

代码语言:javascript
复制
void f(Component&& c)
{
    Component c2 = c; // Expect to use move-constructor
}

c是一个左值。这就是为什么你可以在f中多次使用它。

&&参数表示调用者将不再需要该对象,您可以随意掠夺它。但现在你的函数在概念上是所有者...您调用的子例程不应该掠夺您的对象,除非您依次给予它们权限。

c设为右值会破坏许多用例,例如:

代码语言:javascript
复制
void f(string&& s)
{
    string inputfilename = s + ".in";
    string outputfilename = s + ".out";
    // use s in some other ways
}

要授予子例程洗劫参数的权限,可以使用std::move

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48228987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档