52

I have a function that needs to return a pointer to an object of class myClass. For this purpose I´m using std::unique_ptr.

If the function succeeds, it shall return a pointer to a object with data. If it fails, it should return null.

This is my code skeleton:

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
}

So here goes my questions:

a) Is that (returning an object or null) possible to be done using std::unique_ptr?

b) If possible, how to implement is?

c) If not possible, what are there alternatives?

Thanks for helping.

Mendes
  • 17,489
  • 35
  • 150
  • 263
  • 1
    Creating a unique pointer as `std::unique_ptr myptr;` doesn't allocate any memory, so you don't need to construct it and pass `nullptr` at all. So you can just create one and return it. – AndyG May 17 '15 at 23:55
  • 2
    `nullptr` is a keyword new in C++11 for better support of null pointers. `unique_ptr` can be constructed from `nullptr`, even implicitly. – dyp May 17 '15 at 23:57
  • I see the != operator is being deprecated in C++20 for `unique_ptr`? https://en.cppreference.com/w/cpp/memory/unique_ptr – wcochran Mar 24 '22 at 16:05

4 Answers4

73

Either of the following should work:

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

To test whether the returned object points to a valid object or not, simply use:

if ( returnedData )
{
   // ...
}

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

R Sahu
  • 204,454
  • 14
  • 159
  • 270
11

Yes it's possible. A default constructed unique_ptr is what you want:

Constructs a std::unique_ptr that owns nothing.

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

That is equivalent to the nullptr_t constructor, so perhaps this is more clear:

// No data found
return nullptr;
Barry
  • 286,269
  • 29
  • 621
  • 977
10

Yes, it is possible. A default constructed unique_ptr or one constructed from nullptr can be considered null:

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

To test for null either compare against nullptr or take advantage of conversion to bool:

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

    if (returnedData)
    {
        ... 
    }
}
Chris Drew
  • 14,926
  • 3
  • 34
  • 54
-1

In the latest C++ library there should be a make_unique function in <memory> allowing us to make unique_ptr's as easily as in the C++11 library allows with make_shared and shared pointers.

So you could elucidate the code a little by returning std::make_unique(nullptr)

Plus in the next version of C++ there will be an "option" type which will evaluate as either a some value or a none value. The none value won't be allowed to be treated as if it was a valid value, unlike the empty unique_ptr could be treated like a nullptr. The option type will represent yet another piece of Boost entering the standard library.

cardiff space man
  • 1,442
  • 14
  • 31
  • 1
    Yup, `boost::optional`. Is there a document showing its acceptance into C++17? Edit: I guess this'll do: http://en.cppreference.com/w/cpp/utility/optional – underscore_d Apr 15 '16 at 10:26
  • 1
    @underscore_d At [this](https://meetingcpp.com/index.php/br/items/c17-library-papers-for-cologne.html) the N paper appears to be N4270, although the actual linked version of the paper seems rough (or "drafty" shall we say?) – cardiff space man Apr 15 '16 at 10:36
  • Cool, thanks for the info! I hadn't heard about this being incorporated until now... or if I did hear, then I immediately forgot. – underscore_d Apr 15 '16 at 10:46
  • 3
    Your suggested code is wrong; `std::make_unique` requires a template argument specifying the object type to create, it forwards the function arguments to *that object's constructor*, and it never returns an empty pointer. Creating an empty pointer is just `std::unique_ptr{}`; creating non-empty is `std::make_unique(myClassCtorArgs...)` – boycy Nov 15 '17 at 16:37