c++,析构函数会破坏class成员吗?

c++, will destructor destruct class member?

析构函数在作用域退出或删除等过程中被调用。它旨在 return 动态分配资源到池中。当我显式调用析构函数(空析构函数)时,它/它会对 class 成员做什么?

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

  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 在我的测试期间在析构函数调用后仍然存在。显式调用析构函数不会 return 堆对象的资源。我想仔细检查这是否是预期的行为

我猜直接调用析构函数 z->~Z() 与 "delete z" 不同,一个只会执行在 ~Z() 中实现的,稍后会执行 ~Z() 然后删除 class 成员。

For every new, there should be delete.

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

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

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

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

指针key指向的内存将"stay alive",尽管一旦相应的Z-对象被销毁,您可能会失去与它的任何关系。所以你在这里泄漏内存。为避免这种情况,请添加一个析构函数,即 ~Z() { delete[] key; }.

Z 的成员,即 keycount,一旦拥有的对象被销毁,则不得访问。可能是这些数据成员的"values"不是"cuttet out of system's memory",但是你不能再访问它们了。

关于通过 z->~Z() 调用析构函数:这是非常不寻常的,而且很可能是错误的,除非您打算自己管理内存并且非常清楚自己在做什么。

通常,即在您编码的所有情况下,大约 99.9999% 的情况下,只要对象在其生命周期结束时要被销毁,析构函数就会被隐式触发,即超出范围时的自动变量和动态分配显式调用 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;
}

它只是 "slightly" 更好,因为 class 仍然不覆盖复制或移动 Z 对象(在分配内存时查看 3/5 规则你自己的)。

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

#include <string>
class Z {
public:
    std::string key;
    int count {0};
};

int main() {
    Z z;
    z.count = 1;
    z.key = "K";
}

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

如果您通过 new 创建了 class,您应该调用 delete 而不是直接调用析构函数。在为您调用析构函数后,delete 将 return class 的内存放到堆中。