【问题标题】:Class Destructor类析构函数
【发布时间】:2013-02-19 20:52:31
【问题描述】:

在一个类中,如果我像下面这样声明一个析构函数和一个运算符,那么就会调用一个析构函数。 例如

#include <iostream>
using namespace std;

class CRectangle {
    int width, height;
  public:
    static int n;
    CRectangle (int,int);
    ~CRectangle ();
    int area () {return (width * height);}
    CRectangle operator + (CRectangle);
};
CRectangle CRectangle::operator+ (CRectangle param){
    x+=param.x;
    y+=param.y;
}
CRectangle::CRectangle (int a, int b) {
  width = a;
  height = b;
  n++;
}

CRectangle::~CRectangle () {
    n--;
}
CRectangle::n=0;
int main () {
  CRectangle rect (3,4), rectb (5,6);
  cout << "rect area: " << rect.area() << endl;
  cout << "rectb area: " << rectb.area() << endl;
  rect=rect+rectb;
  return 0;
}

为什么在我执行 +? 操作时会调用析构函数? 程序终止后n的最终值变为-1....

【问题讨论】:

  • 你为什么要这样做?
  • 关键是我能做到吗?
  • 你可以。但这毫无意义。
  • 不……至少它没有做你想做的事。
  • 它确实为两者分配了 0。但是widthheight 以及整个CRectangle 对象在析构函数完成时都不存在了。所以这样做没有意义。

标签: c++ class destructor


【解决方案1】:

析构函数就像一个普通的 void 函数,你可以在技术上做任何你想做的事情。这包括修改即将被销毁的成员变量(毫无意义)。通常你使用这个函数来清理动态分配的内存或者释放对象持有的资源。

当对象超出范围时,通常会为您调用析构函数。将对象的宽度和高度强制为 0 将使区域为 0,但无论如何您都无法在其上调用 area()。已经没了。

更新:

看到更多代码后,我明白为什么您的最终值 n 是错误的。您缺少一个复制构造函数。如果您不提供它,编译器会为您生成一个,并且它不知道递增n。您的operator+ 看起来也不正确(复制和粘贴错误?),但我只能假设那里的某个地方正在进行一些复制,否则它不会编译。尝试添加:

CRectangle::CRectangle(const CRectangle &rhs) : width(rhs.width), height(rhs.height)
{
    ++n;
}

这是Rule of Three 的经典示例。需要复制构造函数、赋值或析构函数的类通常需要这三个。如果你使用的是 C++11,它就变成了Three, Four, or Five 的规则。

【讨论】:

  • 为什么要在复制构造函数中增加 n?复制时我没有删除任何内容,那么到底发生了什么?
  • 因为n 计算有多少个矩形。复制构造函数创建了一个新的 Rectangle,所以你应该数一下。
【解决方案2】:
width=height=0;

这会将widthheight 的值设置为0,但在析构函数完成后就没有用了,因为您不应该再使用该对象或尝试访问其内部变量。也许您可以在析构函数的其他地方使用这些变量,但我不确定您要做什么,但基于示例。你为什么要尝试这个或者你想要解决的“真正”问题是什么并不明显。

如果您以后需要这些值,请使用析构函数设置的一些全局变量。然后每个对象的析构函数都会改变全局变量。

你可以设置变量值,但是在析构函数完成后你不应该使用它们,所以这个例子没有什么实际用处。

【讨论】:

    猜你喜欢
    • 2014-05-27
    • 2011-09-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 2015-06-02
    • 2013-03-22
    • 2013-03-17
    相关资源
    最近更新 更多