析构函数在c ++中调用operator =

时间:2013-11-24 14:17:26

标签: c++ operator-overloading destructor

我有一个班级,其成员有点如下

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? 这与我如何传递参数有关吗?

2 个答案:

答案 0 :(得分:3)

因为你没有将const-reference传递给operator函数(你应该这样)。此函数也应该是const

CRectangle CRectangle::operator+ (const CRectangle &param) 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的副本,您将拥有两个相同的对象:bparam。当此函数返回时,param对象将被销毁。

现在,除了:

之外,一切都会很好
  • 即使bparam是分开的对象,其指针widthheight也指向单个内存位置。 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 &param)

正如您所指出的,operator=也会发生同样的事情。

此外,此代码:

temp.width = new int;
temp.height = new int;
*temp.width = *width + *param.width;
*temp.height = *height + *param.height;

可以重写为(widthheight的类型也应更改为int):

temp.width = width + param.width
temp.height = height + param.height;

如果类似于常规值,则无需将指针作为字段中的字段。