C ++,析构函数会破坏类成员吗?

时间:2018-11-13 09:10:38

标签: c++ destructor

在退出范围或删除等过程中调用析构函数。其目的是将动态分配的资源返回到池中。当我显式调用析构函数(空析构函数)时,它将/对类成员有什么作用?

这不是寻求调试帮助的问题, 示例代码:

  class Z(){
    public:
      Z(){ };
      ~Z(){ };
      int count {0};
  }

  void main()
  {
      Z* z = new Z();
      z->count = 1;
      z->~Z();
      cout << z->count << endl;
  }

在我看来,z-> count在测试期间调用析构函数后仍然有效。显式调用析构函数不会将对象的资源返回到堆。我想仔细检查这是否是预期的行为

我猜直接调用析构函数z->〜Z()与“删除z”不同,一个只会执行在〜Z()中实现的内容,以后将执行〜Z()然后删除该类成员。 / p>

3 个答案:

答案 0 :(得分:6)

析构函数只是要在将类的内存返回到堆或堆栈之前执行的一段代码。它本身不会取消分配该类使用的内存,但是应使用它来清理您可能在构造函数中完成的所有分配。

如果通过new创建了类,则应直接调用delete而不是析构函数。删除将为您调用析构函数后,将类的内存返回到堆中。

答案 1 :(得分:3)

指针123px指向的内存将“保持活动”,尽管一旦破坏了相应的key对象,您可能会失去与其的任何关系。因此,您正在此处泄漏内存。为避免这种情况,请添加析构函数,即Z

一旦拥有对象被破坏,就不能访问~Z() { delete[] key; }的成员,即Zkey的成员。这些数据成员的“值”可能不是“超出系统内存的范围”,但是您不能再访问它们。

关于通过count调用析构函数:这是非常不寻常的,并且很可能是错误的,除非您打算自己管理内存并且非常了解自己在做什么。

通常,即在您编码的所有情况下,大约99.9999%,析构函数都应在生命周期结束时要被销毁的对象隐式触发,例如,对于超出范围的自动变量和在超出范围时的动态分配对象显式调用z->~Z()

因此,程序的(稍微)更好的版本是:

delete z

这只是“稍微”好一点,因为当复制或移动class Z { public: Z(){ key = new char[10]; } ~Z(){ delete[] key; } char* key; int count {0}; }; int main() { Z* z = new Z(); z->count = 1; z->key[0] = 'K'; delete z; } 对象时,该类仍不覆盖(当您自己分配内存时,请参阅3/5规则)。

所以我建议按照以下方式进行操作:

Z

答案 2 :(得分:-1)

  

对于每个 new ,应该有 delete

您正在构造函数中的堆上手动分配内存块。因此,您必须手动将其删除:

Class Z(){
public:
  char* key;
  int count {0};

  Z(){
      key = new char[10];
  };

  ~Z(){
      delete[] key;
  };