0

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

Strategy* strat;

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

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

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

4

2 回答 2

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();
}
于 2012-11-18T18:31:26.657 回答
0

我认为您需要 shared_ptr 和 unique_ptr 的组合。策略类型应该在您的基类之一中,并且您应该根据需要使用共享/唯一 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();
}
于 2012-11-18T19:02:08.053 回答