【问题标题】:copy constructor and temporary object in c++C++中的复制构造函数和临时对象
【发布时间】:2015-09-17 14:53:36
【问题描述】:

我有一个我已经定义的类:

  1. 构造函数
  2. 析构函数
  3. 复制构造函数
  4. 赋值运算符
  5. operator +(Class& obj) 添加两个对象。

operator+按值返回如下:

Base operator +(Base& obj2)
{ 
    cout<<"+ operator called\n"; 
    Base tmp;
    tmp.x=x+obj2.x;
    tmp.y=y+obj2.y;
    return tmp;
}

如果在我的主函数中创建三个对象。应该有三个析构函数调用:

Base obj1(1,2);
Base obj2(1,2);
Base obj3=obj1+obj2; 

问题:

  1. operator +() 的主体中,而return tmp; 我看到它调用了我的复制构造函数。是不是这个 Base 类型的 tmp 被存储在编译器内部生成的临时对象中(例如 Base compiler_tmp=tmp),因此调用了复制构造函数?

  2. 如果是,那么我想它应该代表表达式obj3=obj1+obj2; 的RHS,并且应该在该语句的末尾调用析构函数。

我的上述假设是否正确?或者我在这里遗漏了一点?

【问题讨论】:

  • 相关 - stackoverflow.com/questions/12953127/… - 可能是骗子?
  • 有点题外话:为什么你没有在你的 operator + 实现中通过 const 引用传递 obj2?运算符函数本身也应标记为 const,因为在实例上调用运算符没有理由必须修改该实例。
  • @antred:是的,编写 const & 是一种很好的编程习惯。但不是规则。我只是在尝试所有组合,以查看何时调用复制构造函数以及何时(以及哪一点)调用析构函数。因此,您可以在收集时按值或地址传递,您可以按值或通过 ref 或通过 const ref 收集它。
  • @antred:因为它是一个local variable,在operator+返回后可能会被销毁。因此,您最终可能会引用一个不再存在的变量。
  • @Gombat,@antred 谈论通过引用传递obj2,而不是通过引用返回。

标签: c++


【解决方案1】:

问题有两个方面。有语义复制构造,真正的复制构造和移动构造(您没有定义)。从语义上讲,您在函数执行过程中调用了以下复制构造函数:

  • 返回温度;从你的 tmp 复制构造一个“函数返回空间”中的对象(不管它是什么)
  • obj3 = 中的临时对象是从函数返回空间中的对象复制构造的
  • obj3 是从临时复制构造的

现在,复制省略技术开始发挥作用。根据您的编译器,您可能有许多未调用的复制构造函数。

【讨论】:

  • @SegeyA :我同意第一点。然而,第 1 点和第 2 点指向同一件事。按值返回对象调用复制构造函数(由于将此对象 tmp 复制到由表达式 (obj1+obj2) 表示的临时对象而被调用)。所以第 2 点 - 没有额外的复制构造函数调用。对于第 3 点,将调用赋值运算符(而不是复制构造函数)
  • @anurag86 - 对于第 3 点,OP 显示了一个声明,所以不应该调用复制构造函数而不是 operator= 吗?
  • @Les :哦,是的,你是对的。我在 stackoverflow 的示例中粘贴了 Base Obj3=Obj1+Obj2 但正在尝试 Base Obj3; obj3=obj1+obj2。感谢您指出。
  • @anurag86,没有。从函数返回对象时,语义上有两个副本 - 到“返回空间”和从“返回空间”。
【解决方案2】:
  1. 是的。 operator+ 调用复制构造函数,因为您返回了 Base 的新实例。

  2. 没错。

【讨论】:

  • 不一定。看看@LuchianGrigore 的评论
猜你喜欢
  • 2011-01-20
  • 2015-12-05
  • 1970-01-01
  • 2010-12-22
  • 2016-10-10
  • 2021-07-07
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
相关资源
最近更新 更多