【问题标题】:Why does the copy constructor (of a C++ class) get called when a function returns?为什么函数返回时会调用(C++ 类的)复制构造函数?
【发布时间】:2021-01-04 09:31:41
【问题描述】:

这是一个程序的片段:

cls fun(cls a)
{
     cls v;
     v = a.scale(2.0);
     return v;
}
int main()
{
     cls a(0.0,1.0,2.0);
     cls a2;
     a2 = fun(a);
     return 0;
}

在上面的代码中假设类“cls”的类定义已经定义了构造函数和“scale”函数。我的疑问是在我们已经实例化对象 a2 的主函数中,然后我们将它分配给函数的返回值。那么,为什么在这种情况下会调用复制构造函数呢? (我正在关注一些资源来理解使用 C++ 的 OOP,并且在那里提到在上述情况下调用了复制构造函数。)

另外,如果我在上面的代码中写:

cls a2 = fun(a);

然后,据我了解,必须调用复制构造函数(因为我们将 a2 实例化为某物的副本)。现在, fun(a) 返回一个临时对象,但是复制构造函数的参数需要一个引用值,因为我们不能获取临时对象的引用值,这不应该报错吗?

【问题讨论】:

  • 你确定这里a2 = fun(a);会调用拷贝构造函数吗?不是赋值运算符调用的情况吗?
  • @vahancho:OP 意识到这一点:请参阅以“Also”开头的文本
  • 简单地说必须调用复制构造函数,因为 fun 返回一个临时值。结果必须从函数的堆栈帧复制到 a2。在复制构造函数的持续时间内,编译器会保持函数的堆栈帧处于活动状态。将其视为函数内部的最后思考,而不是函数之后的第一件事。所以对临时的引用仍然有效。注意:较新的 c++ 编译器将消除复制构造函数。它得到elided。该标准定义了何时可能发生这种情况,并避免了大多数无用复制的情况,例如您的情况。
  • @GoswinvonBrederlow 和“当这个可能”正在变成“当这个必须”。

标签: c++ class oop copy-constructor


【解决方案1】:

编译器生成的复制构造函数将const 引用作为参数。

允许匿名临时绑定到const 引用,因此编译通过。

请注意,return v; 创建的隐含值副本在后来的 C++ 标准中省略

【讨论】:

  • 我无法理解这一点:“....由 return v 创建的隐含值副本;...”在您的回答中。你能解释一下你的意思吗?您的意思是 - 执行“return v;”时会发生某种复制(因此调用了复制构造函数)并将复制的值分配给 a2(因为在此步骤中只进行分配,所以复制构造函数不会) t 被调用。)这是你的意思吗?谢谢!
  • @AdityaS:就是这样。早期的编译器会为return v; 获取值副本。谷歌 NRVO 了解更多信息。
猜你喜欢
  • 2013-12-08
  • 1970-01-01
  • 2019-08-12
  • 2019-11-07
  • 2012-02-28
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多