Как удалить указатель, указывающий на динамически размещенный объект внутри динамически размещенного объекта?

У меня есть класс Person. Внутри этого класса Person у меня есть указатель на объект Strategy, который является моим базовым классом (я использую наследование / полиморфизм):

Strategy* strat;

У меня также есть класс Parser. И я говорю эти две строки кода в моем классе синтаксического анализатора:

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

StrategyType является частью иерархии моего базового класса, Strategy. А теперь я хочу удалить страт в конце моей программы, поэтому я не вызываю утечку памяти. Я создал деструктор Person, который в основном удаляет страт. Но проблема в том, что мой деструктор Person вызывается внутри моего класса Parser, где объект Person выпадает из области видимости. Я хочу, чтобы мой объект Person жил дольше этого. Я также мог бы динамически выделить объект Person для решения этой проблемы. Но тогда возникает новый вопрос: как мне удалить динамически размещенные объекты Person?

0

Решение

Насколько я понимаю, у вас есть ситуация, когда ваш класс 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();
}
2

Другие решения

Я думаю, что вам нужно сочетание 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();
}
0