如果我使用 std::move,我如何确保永远不会调用复制构造函数

How I can be ensure that copy constructor will never be called if I use std::move

提问人:user3324131 提问时间:12/27/2020 最后编辑:curiousguyuser3324131 更新时间:12/28/2020 访问量:224

问:

请参阅下面的代码。我评论移动构造函数,而不是编译错误,现在调用复制构造函数!尽管我正在使用 .std::move

如果我使用,我如何确保我的大对象永远不会调用复制构造函数(例如,我忘记添加移动构造函数)?std::move

class MyHugeObject
{
public:
    MyHugeObject()
    {
    }
    MyHugeObject(const MyHugeObject& m)
    {
        std::cout << "copy huge object\n";
    }
    // MyHugeObject(MyHugeObject&& m)
    // {
    //     std::cout << "move huge object\n";
    // }
};

MyHugeObject func()
{
    MyHugeObject m1;
    MyHugeObject&& m2 = std::move(m1);
    return std::move(m2);
}

int main()
{
    auto m = func();
    return 0;
}

输出:

copy huge object
C++ 复制构造函数 move-semantics

评论

5赞 john 12/27/2020
删除 copy 构造函数 。对赋值运算符执行相同的操作。MyHugeObject(const MyHugeObject&) = delete;
3赞 463035818_is_not_an_ai 12/27/2020
FWIW,它本身不会移动任何东西,它只是一个演员std::move
2赞 463035818_is_not_an_ai 12/27/2020
@user3324131不可复制(但可移动)的对象也可以与std::vector
4赞 JHBonarius 12/27/2020
P.s. <-- 由于返回值优化 (RVO),此代码是多余的和糟糕的做法。而且可能也不会做你认为的那样。return std::move(m2);MyHugeObject&& m2 = std::move(m1);
1赞 bitmask 12/27/2020
不要退货。它可以防止省略副本。如果删除移动构造函数,则会有移动构造函数,因此如果无法省略,则必须复制对象。std::move

答:

4赞 Sneftel 12/27/2020 #1

如果您类型的复制构造特别昂贵或有问题,但不是您想要完全禁止的东西,您可以标记复制构造函数。如果没有显式请求,显式复制构造函数将不允许复制(例如,您不能使用它按值自动传递参数),但仍可用于显式复制构造。同时,仍然可以允许隐式移动构造。explicit

评论

0赞 Pete Becker 12/28/2020
当然,如果像问题所假设的那样,他忘记编写移动构造函数,那么他不太可能记得显式地使用复制构造函数。
0赞 user3324131 12/28/2020
@Pete贝克尔。移动构造函数的另一个可能错误:移动构造函数将只绑定到非常量右值。当心 const!不能从中移动常量变量,因为移动构造函数采用非常量(右值)引用。但是,编译器将以静默方式回退到复制构造函数