隐式移动与复制操作和控制

问题描述 投票:2回答:1

当类的成员未定义移动操作时,我正在努力理解隐式移动操作:

int main() {
    struct A // no move: move = copy
    {
        A() = default;
        A(const A&) {
            cout << "A'copy-ctor\n";
        };
        A& operator=(const A&) {
            cout << "A'copy-assign\n";
            return *this;
        }
    };

    struct B
    {
        B() = default;
        A a; // does this make B non-moveable?
        unique_ptr<int> upi;
        // B(B&&) noexcept = default;
        // B& operator=(B&&)noexcept = default;
    };

    A a;
    A a2 = std::move(a); // ok use copy ctor instead of move one
    a2 = std::move(a); // ok use copy assignment instead of move one

    B b;
    B b2 = std::move(b); // why this works?
    b = std::move(b2); // and this works?
    // b = b2; // error: copy deleted because of non-copyable member upi

    cout << "\nDone!\n";
}

所以我看到的是A是不可移动的类,因为其复制控制操作已定义,因此只能复制它,并且任何尝试移动该类对象的尝试都将使用相应的复制操作。

直到这里,如果我正确,那还可以。但是B有一个不可复制的对象upi,它是unique_ptr,因此复制操作被定义为已删除的函数,因此我们无法复制此类的对象。但是此类具有不可移动的对象a,因此我认为此类(B)既不可复制,也不可移动。但是,为什么b2的初始化和b的分配工作正常?到底会发生什么?

B b2 = std::move(b); // ok?!

为什么上面的行调用类A的副本构造函数,并调用B的move构造函数?

  • 对我来说,情况变得更糟:如果我取消对B中的move操作行的注释,则上面的初始化将不会编译抱怨引用已删除的功能,对于分配也是一样!

任何人都可以帮助我,到底会发生什么?在这里发布问题之前,我已经Google搜索并阅读了cppreference和许多网站。

输出:

A'copy-ctor
A'copy-assign
A'copy-ctor
A'copy-assign

Done!
c++ c++11 copy-constructor move-constructor implicit-methods
1个回答
0
投票

std :: move不会强制复制对象。它只是返回&&-reference(允许编译器使用move ctor / assign运算符)。如果是1,2,则复制对象。在3,4种情况下(我认为),物体被移动了。但是A仍被复制,因为它无法移动。

© www.soinside.com 2019 - 2024. All rights reserved.