Как вернуть умный указатель на переменную-член?
Я пытаюсь создать accessor для переменной члена класса с помощью интеллектуальных указателей. Здесь код:
class MyResource
{
};
class MyClass
{
public:
std::unique_ptr<MyResource> getResource();
private:
std::unique_ptr<MyResource> resource;
};
std::unique_ptr<MyResource> MyClass::getResource()
{
return this->resource;
}
Ошибка, которую я пытаюсь скомпилировать:
не может получить доступ к частному члену, объявленному в классе 'std :: unique_ptr <_Ty>'
Добавление .get
в this->resource
конечно, не работает, потому что тип возвращаемого значения изменяется.
Должен ли я использовать unique_ptr здесь? Это просто проблема синтаксиса? Неужели я полностью ошибаюсь?
мой фон с умными указателями: я использую простые указатели уже пару лет отчасти потому, что не могу найти подробное объяснение того, когда использовать какие типы интеллектуальных указателей и как их использовать. Я устал от оправданий, поэтому я просто погружаюсь. Думаю, я понимаю, что такое умные указатели и почему их использовать, но я очень мало разбираюсь в деталях. На данный момент я полностью потерял в к бесконечному Q & A о смарт - указатели.
Ответы
Ответ 1
Самое главное, что нужно знать о умных указателях, это то, что аспект "указателя" не является основной частью их семантики. Существуют интеллектуальные указатели для представления права собственности. Собственность определяется как ответственность за очистку.
Уникальный указатель говорит: "Я являюсь единственным владельцем плацдарма. Я уничтожу его, когда выйду из сферы действия".
Общий указатель говорит: "Я одна из группы друзей, которые разделяют ответственность за плацдарм. Последний из нас, чтобы выйти из сферы действия, уничтожит его".
(В современной программе C++). Необработанный указатель или ссылка говорит: "Я не владею плацдармом, я просто наблюдаю за ним. Кто-то другой несет ответственность за его уничтожение".
В вашем случае использование unique_ptr
для типа члена означает, что MyClass
принадлежит объект MyResource
. Если геттер должен передать право собственности (то есть, если MyClass
отказывается от ресурса для того, кто вызвал геттер), то возвращается unique_ptr
(и вам нужно будет return std::move(resource);
передача прав собственности явно).
Если получатель не должен отказываться от права собственности (что я считаю вероятным сценарием), просто верните простой старый указатель (если возвращать нулевой указатель является опцией) или простой старой ссылкой (если возврат null не является вариантом),
Ответ 2
У вас есть несколько вариантов здесь, в зависимости от семантики, которую вы хотите, чтобы ваш класс наблюдал.
-
Вы хотите отказаться от владения своим ресурсом:
std::unique_ptr<MyResource> MyClass::releaseResource() {
return std::move(this->resource);
}
-
Вы хотите сохранить уникальное право собственности, но кто-то еще его использует:
MyResource& MyClass::getResource() {
assert(this->resource);
return *(this->resource);
}
-
Вы хотите поделиться собственностью, поэтому ресурс не будет уничтожен, если MyClass
выходит за рамки: переключите все на std::shared_ptr<MyResource>
и по-прежнему возвращайтесь по значению.