我在理解这段代码的输出如何出现时遇到问题:
#include<iostream>
using namespace std;
class three_d
{float x,y,z;
public:
three_d(){x=y=z=0;cout<<"\n\tDefault Constructor";}
three_d(float a,float b,float c){x=a;y=b;z=c;cout<<"\n\tOverloaded Constructor";}
three_d(const three_d &obj){x=obj.x;y=obj.y;z=obj.z;cout<<"\n\tCopy Constructor";}
three_d operator+(three_d op2);
three_d operator=(three_d op2);
void show();
~three_d(){cout<<"\n\tDestructor 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<<"\n\n\tValues 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 !!
所以我的问题是:
即使我改变了重载&#34; +&#34;这样的事情:
three_d three_d :: operator +(three_d op2)
{three_d temp;
temp.x = X + op2.x;
temp.y = Y + op2.y;
temp.z = Z + op2.z;
回温;
}
&#34; =&#34;的复制构造函数的输出保持不变(虽然值会改变),即#34; =&#34;只有1个拷贝构造函数。但是我认为必须有2个拷贝构造函数用于&#34; =&#34; 1表示op1对象,1表示* this。
如果我在main中使用简单赋值,如:ob3 = ob1;
复制构造函数按预期调用两次。
请解释一下。
答案 0 :(得分:0)
理解声明的最佳方式,我认为你应该将其视为;
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=
甚至引用{{1}按值(复制)接受输入。这就是为什么你在这里看不到另一个拷贝构造函数的原因。 [这需要专家解释]
operator=
:
这是从7. Copy Constructor
创建另一个临时值,因为您从ob3
返回值。让我们称之为最后一个临时 tmp3 。
operator=
:
当8. Destructor Working !!
完成时,operator+
被破坏。
tmp1
:
当9. Destructor Working !!
完成时,operator+
在作业结束时被破坏。
当我看到tmp3
编译器的结果时,它如下:
4.Copy Constructor
5.Copy构造器
6.Copy构造器
7.Destructor Working !!
8.Destructor Working !!
9.Destructor Working !!
我做过的类似分析如下:
- tmp2 创建
- tmp1 创建
- tmp3 创建
- tmp3 销毁
- tmp1 销毁
- tmp2 销毁
醇>
注意:我们假设您知道使用签名定义GCC
和operator+
的真实方法。(一个是带有两个常量参数的朋友函数,其他通过引用返回等)
答案 1 :(得分:-1)
您的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;
}
<强> P.S。强>
您的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;
}