首页 > 解决方案 > 将成员变量保存在智能指针中以及显式定义的析构函数的重要性

问题描述

我有一个使用旧式 c++ 编写的代码,例如如下所示的原始指针(代码 1):

class Thing { 
    private:
        int data;
        Thing* one;
        Thing* second;
        Thing* previous;
    public:
        Thing():one(0), second(0), previous(0) {}
        // Here is my point of focus
        ~Thing() {
            delete one;
            delete second;
            delete previous;
        }
};

class Container {
    private:
        Thing* thing_ptr;
    public:
        Container() : thing_ptr(new Thing()) {}
        void make_empty {
        /*
            Some algorithm for manually destroying the whole structure.
        */
        }
        ~Container() {
            delete thing_ptr;
        }
};

我的目标是使用智能指针而不是原始指针并执行以下操作(代码 2):

class Thing { 
    private:
        int data;
        std::shared_ptr<Thing> one;
        std::shared_ptr<Thing> second;
        std::shared_ptr<Thing> previous;
    public:
        Thing() : one(nullptr), 
                  second(nullptr), 
                  previous(nullptr) {}

        // Here is my point of focus
        ~Thing() {
        // Do some stuff
        }
};

class Container {
    private:
        std::shared_ptr<Thing> thing_ptr;
    public:
        Container(): thing_ptr(nullptr) {}
        void make_empty {
        /*
            Some recursive algorithm for manually destroying the whole structure.
        */
        }
        /* Some other functions */
        ~Container() {
            // Do some stuff
        }
};

案例 1.如果我不提供适当的析构函数,编译器如何删除共享指针中的指针?删除过程是否会包含来自我的类​​的任何析构函数调用?

情况 2。如果没有明确定义的析构函数,并且有一些其他 shared_ptr 成员变量在类 Thing 中保存类 Field 的对象,如下所示:

class Field {...}

class Thing { 
    private:
        int data;
        std::shared_ptr<Field> field;
        std::shared_ptr<Thing> one;
        std::shared_ptr<Thing> second;
        std::shared_ptr<Thing> previous;
    public:
        Thing() : field(nullptr)
                  one(nullptr), 
                  second(nullptr), 
                  previous(nullptr) {}

        // Here is my point of focus
        ~Thing() {
            // Do some stuff
        }
};

会调用 Field 的析构函数吗?如果没有,那么编译器如何决定如何正确删除这些东西?有缺点吗?

标签: c++memory-managementdestructorsmart-pointersmember-variables

解决方案


成员变量的析构函数会在你的析构函数内容之后自动调用。构造函数以相反的构造顺序调用。

此外,您应该使用 unique_ptr 而不是 shared_ptr。shared_ptr 确实引用了您几乎可以肯定不需要的计数。


推荐阅读