рассмотрим следующий кодповторного назначения shared_ptr внутри указываемого объекта
struct base {
virtual void bar(std::shared_ptr<base>&) = 0;
};
struct foo1 : base { /* ... */ };
struct foo2 : base {
void bar(std::shared_ptr<base>&obj)
{
// ...
if(some_condition)
obj = std::make_shared<foo1>(); // re-assign obj
// ...
}
};
std::shared_ptr<base> x = std::make_shared<foo2>();
x->bar(x); // last line
envoke ли этот код UB? (примечание: повторная присвоение obj уничтожит объект вызова объекта вызова foo2::bar
при вызове из последней строки). Если после этого не будут получены данные из bar
, будет ли код все еще в порядке?
Альтернативный способ кодирования это будет
struct base {
virtual std::shared_ptr<base> bar(std::shared_ptr<base>) = 0;
};
struct foo1 : base { /* ... */ };
struct foo2 : base {
std::shared_ptr<base> bar(std::shared_ptr<base> obj)
{
// ...
if(some_condition)
obj = std::make_shared<foo1>();
// ...
return obj;
}
};
std::shared_ptr<base> x = std::make_shared<foo2>();
x=x->bar(x);
, которые должны быть безопасными в любом случае, не так ли? Является ли дополнительное копирование в этом кодере проблемой производительности?
редактировать. После того, как Крис ответа, я имел взгляд на shared_from_this
, что позволяет альтернативная реализация
struct base : std::enable_shared_from_this<base> {
virtual std::shared_ptr<base> bar() = 0;
};
struct foo1 : base { /* ... */ };
struct foo2 : base {
std::shared_ptr<base> bar()
{
auto obj = shared_from_this();
if(some_condition)
obj = std::make_shared<foo1>();
// ...
return obj;
}
};
std::shared_ptr<base> x = std::make_shared<foo2>();
x=x->bar();
благодарит за напоминание о 'shared_from_this'. – Walter
Пожалуйста, посмотрите мой отредактированный вопрос, то есть код с использованием 'shared_from_this' - вот как это следует использовать? – Walter
уверен, я думаю, что даже более просто это может быть 'if (some_condition) {return std :: make_shared(); } else {return shared_from_this(); } ' –