C++析构函数约定

Zee*_*bit 3 c++ destructor conventions

我在C++中看到了很多代码,例如下面的例子,它通常被推荐为一个约定:

class Foo
{
public:

    Foo()
    {
        bar = new int[100];
        size = 100;
    }

    // ... copy/assignment stuff ...

    ~Foo()
    {
        if (bar) // <--- needed?
        {
            delete[] bar;
            bar = nullptr; // <--- needed?
        }

        size = 0; // <--- needed?
    }

private:

    int* bar;
    int size;
};
Run Code Online (Sandbox Code Playgroud)

对我来说,这三条语句if (bar) { ... },bar = nullptr;以及size = 0;是多余的,原因有二:

  1. delete nullptr; 是完全安全的,它什么都不做.
  2. 如果该对象被销毁,内存被释放,我不应该担心的安全设置bar,以nullptrsize为0.

这些理由是否正确?这些陈述真的是多余的吗?如果是这样,为什么人们继续使用并建议它们?我希望看到一些可以通过保持这一惯例来解决的潜在问题.

Luc*_*ore 6

你是对的,不需要那些,一些编译器无论如何都会优化它们.

然而 - 人们通常这样做的原因是帮助发现问题.例如,假设您没有将指针设置为null.该对象被销毁,但是您错误地尝试访问(曾经是)指针.由于运行时可能无法清除它,因此您仍然可以看到有效的内容.这只有调试才有价值,它仍然是未定义的行为,但它有时会得到回报.

  • `if(bar)`对于调试是没用的,`0` /`nullptr`可能是你用来将内存标记为*destroyed*的*最差*值(一些实现已经为你做了一个更有趣的位模式:``0xDEADBEEF`,至少你想要设置最后一位来将指针标记为无效......) (4认同)
  • +1,虽然`if(bar)`即使对于调试也没用. (2认同)