Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Is it safe to pass an argument like unique_ptr::get() to function

Is is safe to pass a function parameter like getAName(getA().get())? getA() return a object unique_ptr<A>.

I test with the whole code below on VS 2010, it works. But I would like to make sure if it's c++ standard, is it safe with other c++ compilers?

#include "stdafx.h"
#include <memory>
#include <iostream>

using namespace std;

class A
{
public:
    A(){ cout<<"A()"<<endl;}
    ~A(){ cout<<"~A()"<<endl;}

    string name() { return "A"; }
};

std::unique_ptr<A> getA()
{
    return std::unique_ptr<A>(new A());;
}

void getAName(A* a)
{
    if(a)
    {
        cout << a->name().c_str() << endl;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    getAName(getA().get());
    return 0;
}

The outputs in console are:

A()
A
~()

Is it necessary to make code as below for safe for all compilers?

unique_ptr<A> a = getA();
getAName(a.get());
like image 977
ldlchina Avatar asked May 11 '17 01:05

ldlchina


People also ask

Can you pass unique_ptr to a function?

As Sergey explained, std::unique_ptr is a type and you can pass a std::uniqe_ptr instance to a function by value or by reference. Just note that std::unique_ptr is not copyable but movable. Using unique_ptr in this way both documents and enforces the function call's ownership transfer.

What does get () do on a unique_ptr?

unique_ptr::getReturns a pointer to the managed object or nullptr if no object is owned.

Why should you use unique_ptr?

Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another.

What happens when you move a unique_ptr?

A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic.


1 Answers

It is safe. getA() returns a temporary std::unique_ptr, which will be destroyed after the full expression, which constains the invocation of getAName(). So inside the body of getAName() the pointer passed remains valid.

All temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created, ...

Note that if the pointer passed in is stored somewhere (e.g. a global variable) and then used later (i.e. after the invocation of getAName()), the object pointed by the pointer has been destroyed by the temporary std::unique_ptr and the pointer becomes dangled; then deference on it would be UB. If this is the case, as you showed, you might need a named variable for it.

like image 157
songyuanyao Avatar answered Sep 28 '22 13:09

songyuanyao