将成员变量保存在智能指针中,并明确定义析构函数的重要性

时间:2019-05-23 23:13:28

标签: c++ memory-management destructor smart-pointers member-variables

我有一个使用旧式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成员变量在类之类的字段中保存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的析构函数吗?如果否,那么编译器如何决定如何正确删除这些内容?有缺点吗?

1 个答案:

答案 0 :(得分:1)

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

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