当临时返回对象立即分配给另一个对象时调用复制构造函数
Is copy constructor called when the temporary returning object is assigned to another object immediately
我在理解这段代码的输出如何像这样出现时遇到问题:
#include<iostream>
using namespace std;
class three_d
{float x,y,z;
public:
three_d(){x=y=z=0;cout<<"ntDefault Constructor";}
three_d(float a,float b,float c){x=a;y=b;z=c;cout<<"ntOverloaded Constructor";}
three_d(const three_d &obj){x=obj.x;y=obj.y;z=obj.z;cout<<"ntCopy Constructor";}
three_d operator+(three_d op2);
three_d operator=(three_d op2);
void show();
~three_d(){cout<<"ntDestructor Working !!";}
};
three_d three_d::operator+(three_d op2)
{
x=x+op2.x;
y=y+op2.y;
z=z+op2.z;
return *this;
}
three_d three_d::operator=(three_d op1)
{
x=op1.x;
y=op1.y;
z=op1.z;
return *this;
}
void three_d::show()
{
cout<<"nntValues are : x="<<x<<" y="<<y<<" and z="<<z<<"n";
}
int main()
{
three_d ob1(2.1,2,2.2);
three_d ob2(1,1,1), ob3;
ob3=ob1+ob2;
ob1.show();
ob2.show();
ob3.show();
return 0;
}
输出为:
1. Overloaded Constructor
2. Overloaded Constructor
3. Default Constructor
4. Copy Constructor
5. Copy Constructor
6. Destructor Working !!
7. Copy Constructor
8. Destructor Working !!
9. Destructor Working !!
10. Values are : x=3.1 y=3 and z=3.2
11. Values are : x=1 y=1 and z=1
12. Values are : x=3.1 y=3 and z=3.2
13. Destructor Working !!
14. Destructor Working !!
15. Destructor Working !!
所以我的问题是:
- 在输出的第 5 行中,这个复制构造函数是干什么用的? 是用于*这个指针(但由于它是一个指针,我认为它不需要复制构造函数)?第四行是对象 op2(我想) ?
- 如果上面的语句在重载"="时为真,为什么只使用一个复制构造函数(当它也有一个返回值时?
- 临时(返回)对象何时被破坏?
- 请解释输出是如何排序的。
即使我将重载的"+"更改为这样:
three_d three_d::运算符+(three_d op2)
{three_d temp;
temp.x=x+op2.x;
temp.y=y+op2.y;
temp.z=z+op2.z;
返回温度;
}
"的复制构造函数的输出保持不变(尽管值将被更改),即只有 1 个 "=" 的复制构造函数。但是我认为"="必须有 2 个复制构造函数,1 个用于 op1 对象,其他用于 *this .
如果我在 main 中使用简单的赋值,例如 :
ob3=ob1;
则复制构造函数的调用是预期的两倍。请解释一下。
理解该语句的最佳方式,我认为您应该将其视为;
ob3.operator=(ob1.operator+(ob2));
4. Copy Constructor
:这是从ob2
创建一个临时对象,因为您按值调用operator+
。我们称之为临时 tmp2。
5. Copy Constructor
:这是从ob1
创建临时对象,因为您是从按值返回operator+
。我们称之为临时 tmp1。
6. Destructor Working !!
:当operator+
完成时,临时对象 TMP2 被破坏。
-->Important note here
: VC++
和GCC
编译器有趣地通过引用将从operator+
返回的临时对象tmp1传递给operator=
,即使operator=
按值(副本)获取输入。这就是为什么您在此处看不到另一个复制构造函数的原因。[这需要专家解释]
7. Copy Constructor
:这是从ob3
创建另一个临时,因为您按值从operator=
返回。让我们称之为最后一个临时 tmp3。
8. Destructor Working !!
:当operator+
完成时,tmp1
被破坏。
9. Destructor Working !!
:当operator+
完成时,tmp3
将在作业结束时销毁。
当我看到编译器的结果GCC
如下所示:
4.复制构造函数
5.复制构造函数
6.复制构造函数
7.析构函数工作!! 8.析构函数工作!! 9.析构函数工作!!
我所做的类似分析如下:
- TMP2 创建
- TMP1 创建
- TMP3 创建
- TMP3 销毁
- TMP1 销毁
- TMP2 销毁
注意:我们假设您知道使用签名定义operator+
和operator=
的真实方法。(一个是友元函数,需要两个常量参数,另一个是通过引用等返回)
operator+
和operator=
都返回对象。它们是*this
的副本.因此,对复制构造函数的调用。
如果想要避免调用复制构造函数,为了避免复制的成本,请更改这些函数以返回引用。
three_d const& three_d::operator+(three_d op2)
{
x=x+op2.x;
y=y+op2.y;
z=z+op2.z;
return *this;
}
three_d const& three_d::operator=(three_d op1)
{
x=op1.x;
y=op1.y;
z=op1.z;
return *this;
}
附言
operator+
函数修改操作数的 LHS。这种情况并不常见。在表达式中
a = b + c;
你不希望b
被改变。这是值得思考的问题。
如果要以运行良好的方式实现这些功能,则应将它们更改为:
three_d three_d::operator+(three_d const& rhs) const
{
three_d r(*this);
r.x += rhs.x;
r.y += rhs.y;
r.z += rhs.z;
return r;
}
three_d& three_d::operator=(three_d const& rhs)
{
if ( this != &rhs )
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
}
return *this;
}
- 检查哪个对象调用了另一个对象的对象方法
- 为什么数组中对象的析构函数在被另一个对象替换时不被调用?
- 如何创建一个对象创建函数,该函数将由与其关联的名称调用?
- 编译问题 C++ 同时,尝试通过调用另一个对象中的成员函数来创建 std:: 线程
- 我可以制作一个对象方法,如果单独调用,它将自行修改,但如果在复制初始化期间调用,则会返回一个新对象?
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 调用对象类方法,该方法在另一个对象类中的向量中
- 为什么在 C++ 中,当对象包含在另一个对象中时,复制构造函数被调用两次
- 从另一个模板对象调用模板方法时出现奇怪的编译行为
- 使用SWIG包装C 类,该类调用另一个对象成员函数
- 从另一个对象调用成员函数时出现问题
- 将一个对象的函数设置为由arduino库中的另一个对象调用
- c++oop初学者-在一个函数调用中返回向量中每个创建对象的输出和
- 尝试将调用对象与另一个对象进行比较时出现分段错误
- 当一个没有参数的成员函数被c++中的一个对象调用时会发生什么
- 为什么在 const 对象上调用 std::move 在传递给另一个对象时会调用复制构造函数
- 使用“std::function”从另一个对象调用对象的成员
- 从另一个对象调用一个对象的函数时未定义的引用
- 你能同时对一个对象调用几个方法吗
- 类draw()方法在直接调用时有效,但在被另一个对象调用时崩溃