复制构造函数调用两次

Art*_*rez 0 c++

编译器gcc 4.5.3(cygwin)

我试图确定在什么条件下为参数调用复制构造函数,我想找到一种方法来传递一个不需要调用复制构造函数的参数.我构建了以下测试代码来探索此问题.

在以下代码中,为fnc1()调用复制构造函数两次.应该多次调用它的任何理由?

有没有办法没有调用复制构造函数?

# include <iostream>

using namespace std;

class able {
public:
   long x;
   able(): x(1) {}
   able(const able&) {cout << " const "; }
   ~able() { cout << " ~able" << endl; }
};

able fnc1(able x)         { cout << "fnc1(able x)"         ; return x; }
able fnc2(able& x)        { cout << "fnc2(able& x)"        ; return x; }
able fnc3(const able&  x) { cout << "fnc3(const able&  x)" ; return x; }
able fnc4(able const & x) { cout << "fnc4(able const & x)" ; return x; }
able fnc5(able* x)        { cout << "fnc4(able* x)"        ; return *x; }

int main(int argc, char** argv) {

   able* x = new able();
   fnc1(*x);
   fnc2(*x);
   fnc3(*x);
   fnc4(*x);
   fnc5(x);
   cout << "test fini" << endl;
   return 0;
}

output
 const fnc1(able x) const  ~able
  |                 |      |
  |                 |      o first destrucor
  |                 |      
  |                 o second call
  o first call
 ~able
 |
 o second destructor
fnc2(able& x) const  ~able
fnc3(const able&  x) const  ~able
fnc4(able const & x) const  ~able
fnc4(able* x) const  ~able
test fini
Run Code Online (Sandbox Code Playgroud)

Jos*_*eld 6

您正在通过值将able对象传递给函数,然后按值返回它.其中每个都涉及一个副本,并将使用您的复制构造函数.首先将它复制到函数中fnc1(*x);.然后将该副本复制出函数return x;.

至于你的输出顺序,你见证的是:

  1. const

    对象被复制 - 这是作为参数传递给函数的对象.

  2. fnc1(able x)

    执行fnc1.

  3. const

    再次复制对象 - 这是从函数返回的对象.

  4. ~able

    调用析构函数 - 这是在传递被销毁的参数时创建的副本,因为您已到达函数作用域的末尾.

  5. ~able

    调用析构函数 - 这是在行fnc1(*x);完成时从被销毁的函数返回的临时对象.

return x;由编译器引起的第二个副本可能被编译器省略(即使它有一些副作用):

在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作