rvalue作为构造对象的初始化器

时间:2016-01-05 15:09:47

标签: c++

我是编程新手。对不起,我的英语不好。 我试图使用rvalue作为初始对象的初始化器。 因此,根据代码,它将打印出使用的构造函数和赋值运算符。 但结果是对象" what2"和" what3",那些不打印任何东西。 这是代码:

#include <iostream>
using namespace std;
class X{
public:
    int x;
    X()= default;
    X(int num):x{num}{}
    X(const X& y){
        x = y.x;
        std::cout << "copy constructor" << std::endl;
        std::cout << x << std::endl;

    }
    X& operator=(const X& d){
        x = d.x;
        std::cout << "copy assignment" << std::endl;
        return *this;
    }
    X(X&& y){
        x = y.x;
        std::cout << "move constructor" << std::endl;
    }
    X& operator=(X&& b){
        x = b.x;
        std::cout << "move assignment" << std::endl;
        return *this;
    }
};

X operator +(const X& a,const X& b){
    X tmp{};
    tmp.x = a.x +b.x;
    return tmp;
}

int main(int argc, const char * argv[]) {
    X a{7} , b{11};
    X what1;
    cout << "---------------" << endl;
    what1 = a+b;
    cout << "---------------" << endl;
    X what2{a+b};
    cout << "---------------" << endl;
    X what3 = a+b;
    cout << "---------------" << endl;
    std::cout << what1.x << std::endl;
    std::cout << what2.x << std:: endl;
    std::cout <<what3.x << std::endl;
    return 0;
}

输出是:

---------------
move assignment
---------------
---------------
---------------
18
18
18
Program ended with exit code: 0
只有&#34; what1&#34;正确使用分配。 那么,我如何使用rvalue初始化一个对象?并使用operator =来初始化一个对象? 非常感谢你。

3 个答案:

答案 0 :(得分:4)

您的代码可能会导致使用移动操作,但您的编译器已选择elide这些移动并直接在呼叫站点分配operator+的返回值。如果在编译器中禁用了复制省略(GCC或Clang中的-fno-elide-constructors),就会发现这种情况。

您的移动构造函数和赋值运算符将成功用于不允许复制省略的上下文中,例如:

X what2 { std::move(what1) }; //can't elide copy, move constructor used

答案 1 :(得分:0)

GCC提供-fno-elide-constructors选项来禁用copy-elision。如果你想要删除copy-elision,那么使用flag -fno-elide-constructors。有关详细信息,请参阅https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization/27916892#27916892

答案 2 :(得分:0)

以下代码会触发更多构造函数/运算符,检查它以查看在哪种情况下触发

#include <iostream>
using namespace std;
class X{
public:
    int x;
    X()
    {
        x = 0;
        std::cout << "constructor" << std::endl;
    }
    X(int num):x{num}
    {
        std::cout << "list initilizer" << std::endl;
    }
    X(const X& y){
        x = y.x;
        std::cout << "copy constructor" << std::endl;
    }
    X& operator=(const X& d){
        x = d.x;
        std::cout << "copy assignment" << std::endl;
        return *this;
    }
    X(X&& y){
        x = y.x;
        std::cout << "move constructor" << std::endl;
    }
    X& operator=(X&& b){
        x = b.x;
        std::cout << "move assignment" << std::endl;
        return *this;
    }
};

X operator +(const X& a,const X& b){
    X tmp{};
    tmp.x = a.x +b.x;
    return tmp;
}

int main(int argc, const char * argv[]) {
    X a{7} , b{11};
    cout << "---------------" << endl;
    X what1;
    cout << "---------------" << endl;
    what1 = a+b;
    cout << "---------------" << endl;
    X what2(a+b);
    cout << "---------------" << endl;
    X what3 = X(a);
    cout << "---------------" << endl;
    X what4 = X();
    cout << "---------------" << endl;
    X what5 = std::move(what1);
    cout << "---------------" << endl;
    what5 = std::move(what1);
    cout << "---------------" << endl;
    what5 = what1;
    cout << "---------------" << endl;
    return 0;
}