Давайте рассмотрим этот класс, который владеет или просматривает указатель в зависимости от того, как он построен.
template<class T>
class OptionalUniquePtr
{
public:
OptionalUniquePtr(p*)
: m_p(p)
{}
OptionalUniquePtr(std::unique_ptr<T>&& p)
: m_owned_p(std::move(p))
, m_p(p)
{}
T* get()
{
return m_p;
}
private:
std::unique_ptr<T> m_owned_p;
T *m_p;
};
Помимо твиков или оптимизаций, мой вопрос: это плохая идея? Я работаю над кодом, который может по желанию владеть или просматривать некоторые указатели:
std::unique_ptr<Bar> b1 = ...;
Bar *b2 = ...;
// one million lines later
Foo f1(std::move(b1),...); // ownership transfered to f1
Foo f2(b2,...); // just viewing b2, caller manages lifetime. Risky, but usually owners have long lifetime
Представьте, что Foo - это большой класс, который делает что-то на Bar среди других вещей. Я хочу, чтобы Foo был гибким, чтобы принять и то и другое, чтобы он мог иметь внутри OptionalUniquePtr Альтернативой является шаблон Foo, подобный этому
Foo<std::unique_ptr<Bar>> f1(std::move(b1),...);
Foo<Bar*> f1(b2,...);
Преимущество этого второго подхода состоит в том, чтобы быть более явным в отношении владения памятью.
Другой альтернативой является использование std :: shared_ptr для начала, но в огромных кодовых базах это невозможно.
Каково мнение сообщества о OptionalUniquePtr?
Спасибо
Simone