简体   繁体   English

默认情况下应调用移动构造函数

[英]Move constructor should be called by default

In following case where i have created move ctor in Integer class, i am expecting that it should be called by default on rvalue reference while creating Product object but i am getting call of copy constructor only.在以下情况下,我在 Integer class 中创建了移动 ctor,我希望在创建产品 object 时默认在右值引用上调用它,但我只调用构造函数。 Gcc - 7.5.0 on Ubuntu 18 Gcc - Ubuntu 18 上的 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.
}

In above case, move called if i use dId(std::move(xId)) in Product class ctor, I was expecting it should called by default on rvalue reference.在上述情况下,如果我在产品 class ctor 中使用 dId(std::move(xId)) ,则调用移动,我期望它应该在右值引用上默认调用。 In following case i couldn't avoid creating of temporary object of Integer class, Is there any good way to avoid creating of temporary object.在以下情况下,我无法避免创建临时 object 的 Integer class,有什么好方法可以避免创建临时 ZA8CFDE6331BD4B862AC9.

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

    }
    
    Product(10); // inside main

My purpose of above question to build my understanding so that i can utilize temporary object memory better.我上述问题的目的是建立我的理解,以便我可以更好地利用临时 object memory。

You need std::move to "propagate" rvalue-reference-ness.您需要std::move来“传播”右值引用。

Inside the body of the following function:主体内部如下 function:

void foo(int&& x);

…an expression x is an lvalue int . …表达式x是一个左值int Not int&& .不是int&&

References don't really "exist" — even though they are powered by the type system, they are supposed to be treated as aliases (rather than separate entities), so using x inside foo is treated just like using the original, referred-to int inside foo … and doing that would also create a copy, as you know.引用并不真正“存在” ——即使它们由类型系统提供支持,它们也应该被视为别名(而不是单独的实体),因此在foo中使用x就像使用原始的、被引用的一样对待如您所知, int inside foo ... 并且这样做也会创建一个副本。


This will do the job:这将完成这项工作:

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

However, I actually encourage you to take Integer by value:但是,我实际上鼓励您按价值取Integer

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

That way, you can use the same constructor for passing lvalue Integer too, and a copy will be produced if necessary , whereas a move will happen automatically if not (eg by passing in a literal, which will automatically trigger selection of Integer 's move constructor).这样,您也可以使用相同的构造函数来传递左值Integer如果需要,将生成一个副本,而如果没有,则会自动发生移动(例如,通过传入文字,这将自动触发选择Integer的移动构造函数)。

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

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