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

Which constructor is used when an object is initialized with the result of an expression

本文关键字:构造函数 初始化 表达式 结果 对象      更新时间:2023-10-16

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

class X {
    public :
    int x ;
    X(int val) : x(val) {cout<<"one argn" ;} 
    X(const X&xx) {cout<<"const copy constrn" ; x = xx.x ;}
    X(X&xx) {cout<<"non const copy constrn" ; x = xx.x ;}
    X(const X&&xx) {cout<<"const move constrn" ; x = xx.x ;}
    X(X&&xx) {cout<<"non const move constrn" ; x = xx.x ;}
    X operator +(X &ob) {
        X xx(x+ob.x) ; cout<<"addn" ; return xx ;
    }
    X operator=(const X &x) {cout<<"const assignn" ;}
    X operator=(X &x) {cout<<"non const assignn" ;}
    X operator=(const X &&x) {cout<<"const move assignn" ;}
    X operator=(X &&x) {cout<<"non const move assignn" ;}
} ;
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对象是通过哪个构造函数创建的?

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

正如GCC常见问题解答("我的复制构造函数不运行!")中所述,当使用GCC(或clang)与-fno-elide-constructors一起编译以查看每个中间临时对象被复制或移动时,没有理由这样做,因为这会使程序速度慢得多。

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