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

Why constructor is not called when passed by value

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

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

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

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

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

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

return 上没有副本,因为编译器elided 为了效率而进行了副本。如果您将 -fno-elide-constructors 或等效项传递给您的编译器,那么您将看到一个额外的副本。

创建副本以传递值,因此在此处调用复制构造函数。

#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