У меня есть код, который в настоящее время использует raw указатели, и я хочу перейти на интеллектуальные указатели. Это помогает очистить код различными способами. Во всяком случае, у меня есть заводские методы, которые возвращают объекты, и ответственность за них отвечает за их управление. Владение не разделяется, и поэтому я считаю, что unique_ptr
будет подходящим. Объекты, которые я возвращаю, как правило, выводятся из одного базового класса Object
.
Например,
class Object { ... };
class Number : public Object { ... };
class String : public Object { ... };
std::unique_ptr<Number> State::NewNumber(double value)
{
return std::unique_ptr<Number>(new Number(this, value));
}
std::unique_ptr<String> State::NewString(const char* value)
{
return std::unique_ptr<String>(new String(this, value));
}
Возвращаемые объекты довольно часто должны передаваться другой функции, которая работает с объектами типа Object
(базовый класс). Этот код не содержит никаких умных указателей.
void Push(const Object* object) { ... } // push simply pushes the value contained by object onto a stack, which makes a copy of the value
Number* number = NewNumber(5);
Push(number);
При преобразовании этого кода для использования unique_ptrs
я столкнулся с проблемами с полиморфизмом. Первоначально я решил просто изменить определение Push
для использования unique_ptrs
тоже, но это создает ошибки компиляции при попытке использовать производные типы. Я мог бы выделить объекты в качестве базового типа, например
std::unique_ptr<Object> number = NewNumber(5);
и передать их Push
- что, конечно же, работает. Однако мне часто приходится вызывать методы производного типа. В конце концов я решил сделать Push
на указатель на объект, сохраненный unique_ptr
.
void Push(const Object* object) { ... }
std::unique_ptr<Object> number = NewNumber(5);
Push(number.get());
Теперь о причине публикации. Я хочу знать, является ли это обычным способом решения проблемы, которая у меня была? Лучше ли использовать Push
на unique_ptr
против самого объекта? Если да, то как решить проблемы полиморфизма? Я бы предположил, что просто бросать птры не получится. Общеизвестно, что нужно получить основной указатель от умного указателя?
Спасибо, извините, если вопрос непонятен (просто дайте мне знать).
edit: Я думаю, что моя функция Push была немного неоднозначной. Он создает копию базового значения и фактически не изменяет или не сохраняет входной объект.