我有一个班级,其成员有点如下
CRectangle CRectangle::operator+ (CRectangle param) {
CRectangle temp;
temp.width = new int;
temp.height = new int;
*temp.width = *width + *param.width;
*temp.height = *height + *param.height;
return (temp);
}
CRectangle& CRectangle::operator= (CRectangle param) {
*width = *param.width;
*height = *param.height;
return *this;
}
CRectangle::~CRectangle () {
n--;
delete width;
delete height;
}
现在,如果我做
CRectangle a(3, 4), b(5, 6), c;
cout << b.area() << endl; // gives 30
c = a + b;
cout << b.area() << endl; // gives random value
然后在对象b
上调用析构函数。我的意思是,它应该在临时调用,但为什么在b
?
这与我如何传递参数有关吗?
答案 0 :(得分:3)
因为你没有将const-reference传递给operator函数(你应该这样)。此函数也应该是const
:
CRectangle CRectangle::operator+ (const CRectangle ¶m) const {...}
答案 1 :(得分:2)
您的operator+
收到传递给它的参数的副本。
CRectangle CRectangle::operator+ (CRectangle param) {
CRectangle temp;
temp.width = new int;
temp.height = new int;
*temp.width = *width + *param.width;
*temp.height = *height + *param.height;
return (temp);
}
在代码中:
CRectangle a(3,4),b(5,6),c;
c=a+b;
更具体地说,a + b
b
副本传递给a.operator+
。在函数结束时,此副本将被销毁。
所以,总结一下:
您的陈述c = a + b;
可分为两部分:
temp = a + b;
c = temp;
第一个陈述基本上是这样的:
temp = a.operator+(b);
现在,您的operator+
按价值收到了param
。这意味着将创建对象b
的副本,您将拥有两个相同的对象:b
和param
。当此函数返回时,param
对象将被销毁。
现在,除了:
之外,一切都会很好即使b
和param
是分开的对象,其指针width
和height
也指向单个内存位置。 param
的析构函数将释放此内存,b
的指针将指向释放的内存位置。为了防止这种情况,您需要编写copy-constructor:
CRectangle::CRectangle(const CRectangle& param) {
width = new int; // alocate separate memory locations!
height = new int;
*width = *param.width;
*height = *param.height;
}
为避免复制传递,请改为传递const-reference:
CRectangle CRectangle::operator+ (const CRectangle ¶m)
正如您所指出的,operator=
也会发生同样的事情。
此外,此代码:
temp.width = new int;
temp.height = new int;
*temp.width = *width + *param.width;
*temp.height = *height + *param.height;
可以重写为(width
和height
的类型也应更改为int
):
temp.width = width + param.width
temp.height = height + param.height;
如果类似于常规值,则无需将指针作为字段中的字段。