【问题标题】:NULL In a Class Destructor [duplicate]类析构函数中的 NULL [重复]
【发布时间】:2011-02-13 15:15:50
【问题描述】:

可能重复:
Is it worth setting pointers to NULL in a destructor?

在析构函数中给NULL设置一个指针(分配堆内存)是不是没有意义?

class SampleClass
{
    public:
        SampleClass( int Init = 0 )
        {
            Value = new int( Init );
        }

        ~SampleClass( void )
        {
            delete Value;
            Value = NULL; // Is this pointless?
        }

        int *Value;
};

关于类的主题,我什么时候应该使用explicit 关键字?

【问题讨论】:

标签: c++ class null destructor explicit


【解决方案1】:

是的。这是没有意义的,因为对象正在被销毁。 一旦被销毁,将无法到达指针。

【讨论】:

  • 但是对象的内存并没有被擦除。如果你有另一个指向 SampleClass 对象实例的指针(这可能发生 - 错误),你可以访问内存。
  • @mzabsky 如果你有这个问题,你最好使用更智能的指针,这样对象就不会被过早删除。试图防御程序其余部分的错误是毫无意义的。
【解决方案2】:

是的,在析构函数的最后设置指向NULL的指针是没有意义的,因为一旦你离开析构函数,它就不再存在了。

当您想避免隐式转换到您的类类型时,您可以使用显式关键字。 :-)

例如,如果MyClass 有一个采用int 的构造函数和一个函数f(const MyClass&),则您可以调用f 作为

f(42)

f(MyClass(42))

如果你让构造函数显式,只有后者会起作用。它可以使您免于一些不需要的隐式转换。

【讨论】:

    【解决方案3】:

    这并不是毫无意义的。虽然理论上确实不能再次访问该值,但如果有任何其他恶作剧开始发生,将其设置为 NULL 可能会对您有所帮助。

    【讨论】:

    • 虽然它确实有帮助,但它几乎肯定不会像将其设置为一些引人注目的值那样有帮助。
    • 不,NULL 特别表示,我手动设置的。不一样。
    • 0xDEADBEEF 的作用相同,而且它传达了额外的含义“我设置了这个,希望我不会看到它回来”。
    【解决方案4】:

    最好将指针设为NULL。

    如果您在代码中的其他位置删除 SampleClass 实例,然后访问该值(使用另一个指向同一实例的指针),您就会知道出了点问题,因为程序将在 NULL 取消引用时崩溃(所以您会知道您是访问已删除的对象)。

    否则,您可以继续使用已删除的对象并在很久以后才注意到该错误(当内存被另一个对象覆盖时)。此类问题通常极难调试。

    【讨论】:

    • 以同样的方式,建议永远不要将该指针设置为 NULL,如果在同一指针上再次调用 delete,它将通过忽略调用“正常工作”,您将不知道你的代码有隐藏的bug...
    • @David Rodríguez - dribeas 规则是尽快发现错误 = 在取消引用 NULL 值时使程序崩溃。
    • @David Rodríguez,您最好为此使用断言或异常
    • 这是错误的:取消引用指向不再存在的对象的指针只是在这种情况下可能发生的一种错误。举个例子,如果你在析构函数中delete p; p = NULL;,然后检查if (p == NULL),代码仍然是错误的,现在你的检查导致你没有找到这个错误。你是在用寻找一种错误的能力来换取寻找另一种错误的能力。
    • not 将指针设置为NULL 的好处是一个好的调试运行时(就像 Visual C++ 调试堆提供的那样)将填充 freed 的内容具有可识别模式的内存,因此当您崩溃时很容易看出错误是什么;实际上,它使您能够更轻松地捕获这些错误中的大多数,远远超过设置p = NULL; 时能够捕获的。 Michael Burr 在链接的重复问题中更优雅地解释了这一点。
    猜你喜欢
    • 2016-11-26
    • 2012-12-28
    • 2019-12-08
    • 2015-04-05
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    相关资源
    最近更新 更多