如何删除指向动态分配对象内动态分配对象的指针?

时间:2012-11-18 18:10:19

标签: c++ pointers dynamic allocation delete-operator

我有一个Person类。在这个Person类中,我有一个指针Strategy对象,它是我的基类(我使用的是继承/多态):

Strategy* strat;

我也有一个Parser类。我在解析器类中说了这两行代码:

StrategyType* newStrat; = new StrategyType;
person.strat = newStrat

StrategyType是我的基类Strategy的层次结构的一部分。现在,我想在程序结束时删除 strat ,所以我不会导致内存泄漏。我创建了一个Person析构函数,它基本上删除了 strat 。但问题是,我的Person析构函数在我的Parser类中被调用,其中Person对象超出了范围。我希望我的Person对象比这更长寿。我也可以动态分配Person对象来解决这个问题。但接下来的问题是,如何删除动态分配的Person对象?

2 个答案:

答案 0 :(得分:2)

根据我的理解,您的Parser类具有Person对象,但您希望Person对象能够比Parser对象更长。这就是std::shared_ptr的用途。

class Parser
{
public:
    Parser(std::shared_ptr<Person> person)
        :m_person(std::move(person))
    {
        // probably want to use a unique_ptr for strat, but one thing at a time
        m_person->strat = new StrategyType;
    }
private:
    std::shared_ptr<Person> m_person;
};

int main()
{
    auto person = std::make_shared<Person>();

    {
        Parser parser(person);
        // parser shares person            
    }
    // parser is destroyed, but person lives on

    person->do_something();
}

答案 1 :(得分:0)

我认为你需要shared_ptr和unique_ptr的组合。 策略类型应该在你的一个基类中,你应该根据需要使用shared / unique ptr,现在就是unique_ptr。这样你就可以确定重新分配不会泄漏或更好地检查它是否已被分配。

显然你不希望会员变量公开,但这里是为了示范。

#include <memory>

class StrategyType
{};

class PersonBase
{
public:
    std::unique_ptr<StrategyType> strat;
};

class Person : public PersonBase
{
public:

    void do_something()
    {
        double d = 0;
        d = d + 9;
        d = d * d;
    }
};

class Parser
{
public:
    //  makes no sense in moving shared_ptr
    //  hence pass by value
    Parser(std::shared_ptr<Person> _person)
        :m_person(_person)
    {
        // probably want to use a unique_ptr for strat, but one thing at a time
        m_person->strat.reset(new StrategyType);
    }
private:
    std::shared_ptr<Person> m_person;
};

int main()
{
    auto person = std::make_shared<Person>();

    {
        Parser parser(person);
        // parser shares person            
    }
    // parser is destroyed, but person lives on

    person->do_something();
}