С++ std:: unique_ptr return from function и test для null

У меня есть функция, которая должна вернуть указатель на объект класса myClass. Для этого я использую std::unique_ptr.

Если функция завершается успешно, она возвращает указатель на объект с данными. Если он терпит неудачу, он должен вернуть null.

Это мой скелет кода:

std::unique_ptr<myClass> getData()
{
   if (dataExists)
      ... create a new myClass object, populate and return it ...

   // No data found
   return std::unique_ptr<myClass> (null); <--- Possible ?
}

on main:

main()
{
   std::unique_ptr<myClass> returnedData;

   returnedData = getData();

   if (returnedData != null)   <-- How to test for null ?
   {
      cout << "No data returned." << endl;
      return 0;
   }

   // Process data
}

Итак, вот мои вопросы:

a) Возможно ли (возвращение объекта или null) с помощью std::unique_ptr?

b) Если возможно, как реализовать?

c) Если это невозможно, какие существуют альтернативы?

Спасибо за помощь.

Ответ 1

Любое из следующих действий должно работать:

return std::unique_ptr<myClass>{};
return std::unique_ptr<myClass>(nullptr);

Чтобы проверить, указывает ли возвращенный объект на действительный объект или нет, просто используйте:

if ( returnedData )
{
   // ...
}

См. http://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool.

Ответ 2

Да, это возможно. По умолчанию построено unique_ptr:

Создает a std::unique_ptr, которому ничего не принадлежит.

// No data found
return std::unique_ptr<myClass>{};

Это эквивалентно конструктору nullptr_t, поэтому, возможно, это более понятно:

// No data found
return nullptr;

Ответ 3

Да, это возможно. По умолчанию построенный unique_ptr или построенный из nullptr может считаться null:

std::unique_ptr<MyClass> getData()
{
    if (dataExists)
        return std::make_unique<MyClass>();
    return nullptr;
}

Чтобы проверить значение null, сравните его с nullptr или воспользуйтесь преобразованием в bool:

int main()
{
    std::unique_ptr<MyClass> returnedData = getData();

    if (returnedData)
    {
        ... 
    }
}

Ответ 4

Да, это возможно.

На странице справки std:: unique_ptr:: unique_ptr():

constexpr unique_ptr();

Создает a std::unique_ptr, которому ничего не принадлежит.

Итак, в основном:

std::unique_prt<myClass> getData()
{
   myClass* data_ptr = nullptr;

   if (dataExists)
      // Create a new myClass object, populate and store in 'data_ptr'

   return std::unique_ptr<myClass>(data_ptr); //'data_ptr' is either valid pointer or nullptr
}

Для проверки недействительности используйте std:: unique_ptr:: operator bool - просто используйте его как условие внутри оператора if:

main()
{
   std::unique_ptr<myClass> returnedData = getData();

   if (returnedData)
   {
       // Data OK - Process
   }

}

В качестве справочной страницы для std:: unique_ptr:: operator bool говорит:

Проверяет, имеет ли *this объект, т.е. get() != nullptr.

Ответ 5

В последней библиотеке С++ должна быть функция make_unique в <memory>, позволяющая нам сделать unique_ptr так же легко, как в библиотеке С++ 11, с помощью make_shared и общих указателей.

Итак, вы можете немного разъяснить код, вернув std::make_unique(nullptr)

Плюс в следующей версии С++ появится тип "option", который будет оцениваться как значение some или значение none. Значение none не будет обрабатываться так, как если бы оно было допустимым значением, в отличие от пустого unique_ptr можно было бы обработать как nullptr. Тип опции будет представлять еще одну часть Boost, которая войдет в стандартную библиотеку.