0

我看到了这段代码。在析构函数之后使用 : int area () {return (*width * *height);} 是否有效?

// example on constructors and destructors
#include <iostream>
using namespace std;

class CRectangle {
    int *width, *height;
 public:
 CRectangle (int,int);
~CRectangle ();
int area () {return (*width * *height);}
};

CRectangle::CRectangle (int a, int b) {
 width = new int;//
 height = new int;//
 *width = a;//
 *height = b;//
}//

CRectangle::~CRectangle (){//
 delete width;//
 delete height;//
}////
4

5 回答 5

1

在这段代码中,你没有int area () {return (*width * *height);}在析构函数之后“使用”,你只是在析构函数之后声明了它。

这是有效的。

但是,如果您询问其他代码是否可以area在对象被销毁后调用,则不能。

于 2013-05-20T07:16:33.107 回答
1

在析构函数之后使用 : int area () {return (*width * *height);} 是否有效?

实际上,您不能使用包含方法的对象,area因为它已被破坏。

例子:

CRectangle *r = new CRectangle(100,200);
...
delete r;

r->area(); 
// There's no "r" anymore so it doesn't matter *width or *height are valid or not
// you can't access to "area" method
于 2013-05-20T07:17:37.230 回答
1

*heightfree或者free 之后使用肯定是无效的*width。但是,在对象被销毁后,一般使用它也是无效的。由于指针的释放发生在析构函数中,这是可以接受的。

但是,您的代码违反了“三原则”:当一个类分配自己的内存时,它需要有一个复制构造函数和一个赋值运算符,否则您将泄漏内存或“使用不应该使用的内存”使用“(或两者)。

考虑:

...
CRectangle r1(10,25);
CRectangle r2(10,26);

CRectangle bigger(0,0);

if (r1.area() > r2.area())
   bigger = r1;
else
   bigger = r2;

{
   CRectangle r3(200, 300);
   r1 = r3;
}   // r3 is destroyed here.
cout << r1.area() << endl;   // Bang, using freed memory. 

在您的复制构造函数和赋值运算符中,您需要使相关的旧数据释放并分配新数据,具体取决于您在做什么。

[当然,对两个整数执行此操作完全浪费了内存空间和时间——即使是我所知道的最好的内存分配,这样使用的内存也是类中只有两个整数的五倍。]

于 2013-05-20T07:24:28.707 回答
0

是的,在释放悬空指针后尊重它是未定义的行为。

于 2013-05-20T07:16:24.893 回答
0

您是否在询问area()销毁对象后调用对象是否合法?

不。

绝不。

为什么你甚至会认为你可以、应该或会!

于 2013-05-20T07:17:29.130 回答