c++ - 默认情况下应调用 move 构造函数

标签 c++ c++11 move move-semantics move-constructor

在以下情况下,我在 Integer 类中创建了 move ctor,我希望在创建 Product 对象时默认在右值引用上调用它,但我只调用复制构造函数。 Ubuntu 18 上的 Gcc - 7.5.0

#include<iostream>
using namespace std;

class Integer 
{
    int *dInt = nullptr;
public: 
    Integer(int xInt)  {
        dInt = new int(xInt);
        cout<<"Integer Created"<<endl;
    } 
    Integer(const Integer &xObj)
    {
        cout<<"Copy called"<<endl;
        dInt = new int(xObj.mGetInt());
    }

    Integer(Integer &&xObj)
    {
        cout<<"Move called"<<endl;
        dInt = xObj.dInt;
        xObj.dInt = nullptr;
    }

    Integer& operator=(const Integer &xObj)
    {
        cout<<"Assignment operator called"<<endl;
        *dInt = xObj.mGetInt();
        return *this;
    }

    Integer& operator=(Integer &&xObj)
    {
        cout<<"Move Assignment operator called"<<endl;
        delete dInt;
        dInt = xObj.dInt;
        xObj.dInt = nullptr;
        return *this;   
    }
    ~Integer() 
    {
        cout<<"Integer destroyed"<<endl;
        delete dInt;
    }

    int mGetInt() const {return *dInt;}
};

class Product 
{
    Integer dId;
public: 
    Product(Integer &&xId)
    :dId(xId)
    {

    }
};
int main () 
{
    Product P(10); // Notice implicit conversion of 10 to Integer obj.
}

在上面的情况下,如果我在 Product 类 ctor 中使用 dId(std::move(xId)) ,则 move 被调用,我期望它应该在右值引用上默认调用。 在以下情况下,我无法避免创建 Integer 类的临时对象,有什么好的方法可以避免创建临时对象。

    Product(const Integer &xId)
    :dId(xId)
    {

    }
    
    Product(10); // inside main

我提出上述问题的目的是为了加深我的理解,以便我可以更好地利用临时对象内存。

最佳答案

您需要 std::move 来“传播”右值引用。

在以下函数体内:

void foo(int&& x);

…表达式x是左值int不是 int&&

引用并不真正“存在” - 尽管它们由类型系统提供支持,但它们应该被视为别名(而不是单独的实体),因此使用 x foo 中的 的处理方式就像在 foo 中使用原始的、引用的 int 一样……这样做也会 如您所知,创建一个拷贝。


这将完成这项工作:

Product(Integer&& xId)
    : dId(std::move(xId))
{}

但是,我实际上鼓励您按值获取Integer:

Product(Integer xId)
    : dId(std::move(xId))
{}

这样,您也可以使用相同的构造函数来传递左值Integer,并且如果需要的话将生成一个拷贝,而如果没有则将自动发生 move (例如,通过传入一个文字,这将自动触发选择 Integer 的 move 构造函数)。

关于c++ - 默认情况下应调用 move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63204959/

相关文章:

c++ - Opencv VideoWriter 只保存一帧

c++ - 在将实例作为基础对象传递的函数中使用复制构造函数创建实例的拷贝

c++ - "invalid use of non-static data member"当通过友善的输出运算符访问模板化类的字段时

c++ - Qt QTcpSocket 异步写入

c++ - 正确使用 MPI 和 std::string

c++ - 在 C++0X 中评估 auto 的类型

c++ - 将移位的无符号数字用作数组的索引号是一个好习惯

c++ - 使用 move() 而不是 std::move() 有什么陷阱吗?

html - 使用氚 move html 元素

powershell - 如果文件名包含字符串,则将文件移到目标位置