c++ - 指向 "raw"资源的指针应该在析构函数中归零吗?

标签 c++ destructor raii

当我在 C++ 类中包装“原始”资源时,在析构函数代码中,我通常只是简单地释放分配的资源,而不注意其他步骤,例如将指针清零等。 例如:

class File
{
public:
  ...

  ~File()
  {
    if (m_file != NULL)
      fclose(m_file);
  }

private:
  FILE * m_file;
};

我想知道这种代码风格是否包含一个潜在的错误:即是否有可能多次调用析构函数?在这种情况下,正确的做法是在析构函数中将清除指针以避免双重/多重破坏:

~File()
{
  if (m_file != NULL)
  {
    fclose(m_file);
    m_file = NULL; // avoid double destruction
  }
}

可以为堆分配的内存做一个类似的例子:如果 m_ptr 是一个指向用 new[] 分配的内存的指针,下面的析构函数代码可以吗?

// In destructor:
delete [] m_ptr; 

或者是否也应该清除指针以避免双重破坏?

// In destructor:
delete [] m_ptr;
m_ptr = NULL; // avoid double destruction

最佳答案

没有。如果您有 Close() 函数或类似函数,它会很有用:

void Close()
{
    if (m_file != NULL)
    {
        fclose(m_file);
        m_file = NULL;
    }
}
~File()
{
    Close();
}

这样,Close() 函数是幂等的(您可以根据需要多次调用它),并且可以避免在析构函数中进行一次额外的测试。

但由于 C++ 中的析构函数只能调用一次,因此将 NULL 分配给指针毫无意义。

当然,除非出于调试目的,特别是如果您怀疑双重删除。

关于c++ - 指向 "raw"资源的指针应该在析构函数中归零吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9084225/

相关文章:

c++ - 在 Qt 中制作关于 GUI 窗口的游戏

c++ - C++中的内置哈希表

c++ - 如何创建锁定和解锁互斥锁的智能指针?

rust - 是否可以同时在范围末尾丢弃和消耗 self ?

c++ - 停止对 operator delete 的隐式转换

c++ - 哪些语言生成字节码并可以在 C++ 中加载/执行

c# - 析构函数和终结器方法的区别

c++ - 了解 C++ 析构函数在派生类中的行为

C++ 级联破坏具有静态存储持续时间的对象

c++ - 如何使用资源获取即初始化来实现构建器模式?