使用表达式的结果初始化对象时使用的构造函数

时间:2014-10-09 13:27:37

标签: c++

我有以下简单的c ++代码:

class X {
    public :
    int x ;
    X(int val) : x(val) {cout<<"one arg\n" ;} 
    X(const X&xx) {cout<<"const copy constr\n" ; x = xx.x ;}
    X(X&xx) {cout<<"non const copy constr\n" ; x = xx.x ;}
    X(const X&&xx) {cout<<"const move constr\n" ; x = xx.x ;}
    X(X&&xx) {cout<<"non const move constr\n" ; x = xx.x ;}
    X operator +(X &ob) {
        X xx(x+ob.x) ; cout<<"add\n" ; return xx ;
    }
    X operator=(const X &x) {cout<<"const assign\n" ;}
    X operator=(X &x) {cout<<"non const assign\n" ;}
    X operator=(const X &&x) {cout<<"const move assign\n" ;}
    X operator=(X &&x) {cout<<"non const move assign\n" ;}
} ;

main() {
    X   x1(10), x2(x1) ;
    cout<<"$$$$$$$$$$$$$$\n" ;
    X   x3 = x1+x2 ;//does not invoke move/copy constr ---> do not know why
    cout<<"###########"<<x3.x<<endl ;
    cout<<"$$$$$$$$$$$$$$\n" ;
    vector<X>   v ;
    v.push_back(X(100)) ;//invokes move constr

}

通过哪个构造函数创建对象 x3

1 个答案:

答案 0 :(得分:4)

在stackoverflow上有这个问题的重复重复,移动/复制已被删除,请参阅http://en.wikipedia.org/wiki/Copy_elision

正如GCC FAQ("My copy constructor doesn't run!")中所述,当使用gcc(或clang)编译-fno-elide-constructors来查看每个中间临时对象被复制或移动时,但没有理由这样做是因为它会使你的程序慢得多。

您正在观察的是X内的operator+是在为x3保留的堆栈位置构建的,因此不需要复制或移动,因为{已在正确的位置构建具有正确值的{1}}。如果您打印出X的地址和xx的地址,您会看到它们是同一个对象。