gipert
gipert

Reputation: 207

Return private unique_ptr in public member function

Consider the following class prototype:

class ObjHandler {

    std::unique_ptr<Obj> GetPtr() { return obj; }

  private:
    std::unique_ptr<Obj> obj;
};

This generates a compile-time error saying that the copy constructor of std::unique_ptr is deleted. Why here move semantics are not applied? Is it related to the fact that GetPtr() does not own the obj pointer? How should I implement my code (I need a member function that returns an owning pointer to the stream with the minimum overhead)?

Upvotes: 5

Views: 1653

Answers (2)

flogram_dev
flogram_dev

Reputation: 42868

Why here move semantics are not applied?

Because obj is not a local variable, so the language doesn't allow it to be implicitly moved.

You can move it by using std::move:

std::unique_ptr<Obj> GetPtr() { return std::move(obj); }

Although if this is really what you want, I'd recommend naming the function something that makes it clear that the ownership is being transferred (i.e. that this->obj becomes null), e.g. MovePtr.

The name GetPtr makes it sound like it doesn't modify this->obj and just returns a non-owning pointer to the managed object, i.e. that its behavior is the following:

Obj* GetPtr() const { return obj.get(); }

Upvotes: 7

xtofl
xtofl

Reputation: 41519

The unique means actually 'unique ownership'. It makes no sense that you would create a copy of the ownership, since then it would not be unique anymore.

What you probably want is returning a reference to the contained object, or a non owning pointer:

class ObjHandler {
   Object &get(){ return *obj; }
   Object *GetPtr() { return obj.get(); }
private:
   unique_ptr<Object> obj;
};

This post is a very good talk on the what/where/why of using smart pointers.

And the CppCoreGuidelines have a hint on this, too: a raw pointer is by definition indication of the fact that the object is not owned.

Upvotes: 10

Related Questions