为什么在按值传递时不调用构造函数

时间:2015-10-14 13:09:37

标签: c++ constructor copy-constructor

我正在阅读复制构造函数以及它们通常作为常量引用接收参数的方式。 Why should the copy constructor accept its parameter by reference in C++? 我编写了一个代码片段,用于测试当按值接收参数时,是否创建了副本(如所提供链接的接受答案中所述)。 但是,当按值接收对象时,我没有看到调用的构造函数。 请解释原因?当一个对象按值返回时,是不是创建了一个副本?再也没有构造函数在那里调用。为什么呢?

class Vector
{
   public:
    Vector(){cout << "Vector constructor"<<endl;}
    ~Vector(){cout << "Vector destructor"<<endl;}

};
Vector use(Vector z)
{
   cout << "At call" << endl; 
  Vector v;
  cout << "after definition" << endl;
  return v;
}
int main()
{
    Vector t;
    cout << "After irrelevant" << endl;
 use(t);
 cout << "After use"<< endl;
}

输出如下:

Vector constructor
After irrelevant
At call
Vector constructor
after definition
Vector destructor
Vector destructor
After use
Vector destructor

Update1:​​我在初始示例中错过了添加复制构造函数。一旦完成,代码就会按预期运行。

2 个答案:

答案 0 :(得分:3)

当按值传递对象时,不会调用默认构造函数,复制(或移动)构造函数是。

如果我们跟踪这样的复制构造函数:

class Vector
{
   public:
    Vector(){cout << "Vector constructor"<<endl;}
    Vector(const Vector&) {cout << "Vector copy constructor"<<endl;}
    ~Vector(){cout << "Vector destructor"<<endl;}
};

然后我们看到被调用的构造函数:

Vector constructor
After irrelevant
Vector copy constructor //here
At call
Vector constructor
after definition
Vector destructor
Vector destructor
After use
Vector destructor

返回时没有副本,因为编译器的副本为elided以提高效率。如果您将-fno-elide-constructors或等效文件传递给编译器,那么您将看到另一个副本。

答案 1 :(得分:0)

创建复制以传递值,因此在那里调用复制构造函数。

#include <iostream>
using std::cout;
using std::endl;
class Vector
{
    public:
    Vector(){cout << "Vector constructor"<<endl;}
    Vector(const Vector&){cout << "Vector copy constructor"<<endl;} // add this line
    ~Vector(){cout << "Vector destructor"<<endl;}

};
Vector use(Vector z)
{
     cout << "At call" << endl; 
    Vector v;
    cout << "after definition" << endl;
    return v;
}
int main()
{
    Vector t;
    cout << "After irrelevant" << endl;
    use(t);
    cout << "After use"<< endl;
}

输出:

Vector constructor
After irrelevant
Vector copy constructor
At call
Vector constructor
after definition
Vector destructor
Vector destructor
After use
Vector destructor