是否应始终在析构函数中清除/清零成员数据?

时间:2015-02-08 19:56:44

标签: c++ destructor

是否有充分理由清除/归零析构函数中对象的基本成员数据?为了整洁或隐私,似乎应将此视为标准做法,因为有可能的方法从已删除的对象重新读取数据:

#include <iostream>

class Box {
    public:
        Box(int s) : secret(s), buffer(this) {}
        ~Box() {}
        /*BETTER DESTRUCTOR ~Box() {secret = 0;}*/
        void print() {std::cout << secret << std::endl;}
    private:
        void* buffer;
        int secret;
};

int main() {
    Box* carton = new Box(8675309);
    Box* crate = carton;
    delete carton;
    crate->print();
}

(请注意buffer只是必要的,因为如果没有它,会在secret之前覆盖crate->print()。)

&#34; 花费太多时间&#34;将成员数据归零以使其被认为是不值得的(特别是如果你必须遍历数组并将每个元素归零)?

显然,对于像STL容器这样的更复杂的数据成员而言,这不是问题,因为their destructors clear their data以及pointers should not be cleared用于调试目的。

2 个答案:

答案 0 :(得分:7)

IF 你的班级包含&#34;秘密&#34;事情,然后在解构时清除它将有助于保持它不被保存在你不再拥有的记忆中。但这并不意味着当你的应用程序使对象处于活动状态时,你可以阻止某人拍摄内存的快照,所以作为安全措施,它很糟糕......

但总的来说,不,析构函数不应该将类中的内容归零。这是浪费时间。

这与&#34不同;它不应该删除动态分配结构中的成员&#34;当然,例如std::vector将会做什么。它会破坏向量的所有内容,因为没有告诉这些元素的析构函数是什么。

答案 1 :(得分:1)

一个相当不错的优化工具会删除您的secret = 0作业。

原因很简单。最简单的优化之一是删除无效的指令。这类指令的一类通用是写入,后面没有读取。由于this->secret=0是析构函数中的最后一个语句,因此编译器可以轻松地确定您再也不会读取secret。删除指令很容易。

您可能想知道为什么要进行此优化,这种情况会发生多长时间?答案是&#34;经常&#34;,因为优化不是孤立发生的。例如,当内联函数在调用者没有检查错误代码时返回错误代码时,这种无读写是常见的。在内联之后,这是对错误代码的写入而没有匹配的读取。