c++unique-ptrownership-semantics

calling functions which take unique_ptr object


I have a function in which the callback receives an event holding a unique_ptr instace of data. I can retrieve the char* through event.data.get() which should give me the pointer but not ownership allowing the object to freely delete it. Now I have another function which takes a unique_ptr instance of otherdata and of course manages ownership so the function is free to release it. So I'm trying to take data from the callback and pass it into the function which takes otherdata safely.

void cbdata(const DataEvent& event){
                char* datatobewritten = event.data.get();
                stream.write(std::move(datatobewritten),event.length));
            }

The above example does seem to work but I'm not sure if it's the right way to do it. Is event giving up ownership? And if so, is it safe to give up the ownership?

And why does this result in a compiler error: Call to implicitly-deleted copy constructor of 'std::unique_ptr<char []>'?

void cbdata(const DataEvent& event){
                stream.write(event.data,event.length);
            }

If event.data gives me a unique_ptr and stream.write takes a unique_ptr then shouldn't the above code work fine? Or this

stream.write(std::move(event.data), event.length);

Sorry my C++ knowledge is really limited so unique_ptr and move semantics are pretty confusing.


Solution

  • The stream.write() probably takes a const char *, if so you won't need to std::move() to pass data to it. std::move() is used when you need to change data ownership of an unique_ptr. But in this case data is own by event and we only temporarily let stream.write() access it.

    void cbdata(const DataEvent& event){
        const char* datatobewritten = event.data.get();
        stream.write(datatobewritten, event.length);
    }
    

    If stream.write() takes a std::unique_ptr, so you'd need to std::move() the data from event.data to this function. After this move, event.data is in a "moved from" state and can't access the data anymore.

    void cbdata(DataEvent& event){
        stream.write(std::move(event.data), event.length);
        // now 'event.data' owns nothing and holds a null pointer
    }