【问题标题】:Why X(X&) could be called for two times?为什么 X(X&) 可以被调用两次?
【发布时间】:2012-09-26 05:00:13
【问题描述】:

我写了这段代码:

    struct X{
        int val;

        void out(const string& s, int nv)
            {cerr<<this<<"->"<<s<<": "<<val<<"("<<nv<<")\n";}

        X() {out("X(int)",0); val=0;}
        X(int v){out("X(int)",v); val=v;}
        X(const X& x){out("X(X&)",x.val); val=x.val;}
        X& operator=(const X& a)
            {out("X::operator=()",a.val); val=a.val; return *this;}
        ~X() {out("~X()",0);}
    };

    X copy(X a) {return a;}

    int main{
        X loc2;
        X loc(5);
        loc2 = copy(loc);
        return 0;
    }

输出是这样的(在 VS2010 中):

003BFAA0->X(int): -858993460(0)
003BFA94->X(int): -858993460(5)
003BF964->X(X&): 723486321(5)
003BF994->X(X&): -858993460(5)
003BF964->~X(): 5(0)
003BFAA0->X::operator=(): 0(5)
003BF994->~X(): 5(0)

前两行很好。但是第三和第四行显示它调用了 X(X&) 两次。副本(X a)中只有一个“X a”。为什么 X(X&) 会被调用两次?

【问题讨论】:

    标签: c++ constructor destructor


    【解决方案1】:

    为什么X(X&amp;)会被调用两次?

    用函数调用:

    loc2 = copy(loc);    
    

    copy(loc); 两次调用复制构造函数:

    1. 创建传递给函数的参数loc 的副本。
    2. 创建返回对象a的副本。

    在 C/C++ 中,函数的参数默认按值传递。因此,在函数调用中接收到的不是实际参数,而是传递的对象/变量的副本。这个副本是通过调用复制构造函数创建的。
    您的 copy() 函数也再次按值返回,从而导致调用复制构造函数。

    请注意,在某些情况下,编译器可能会省略(删除)复制构造函数的调用并内联构造对象,这种现象称为复制省略。一般情况下,您不应该编写任何代码根据调用复制构造函数的次数产生副作用。

    【讨论】:

      【解决方案2】:

      当“return a”被执行时,X类型对象的副本被创建,因为返回类型是X(不是X&)。 (如果是 X& - 这也是一个错误 - 复制函数“a”的形式参数是一个具有局部范围的变量)

      【讨论】:

        猜你喜欢
        • 2021-07-13
        • 2021-11-25
        • 2015-12-24
        • 2012-12-10
        • 2014-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多