Move std::unique_ptr to Pass to a Function or Assign to Another Variable

The std::unique_ptr has unique ownership of the object it manages. That means that more than one std::unique_ptr object can not contain the managed object pointer. That’s why we can not assign a std::unique_ptr to another one. For the same reason, we can not pass std::unique_ptr as an argument of a function.

But we can always move the ownership of the object to a new std::unique_ptr. After the move the assigned unique_ptr will own the managed object pointer. We’ll no longer be able to access the object from the old (source) unique_ptr.

class C {
public:
  C() {
    std::cout << "Constructing the class..." << std::endl;
  }

  ~C() {
    std::cout << "Destructing the class..." << std::endl;
  }

  void f() {
    std::cout << "Printing from function f()..." << std::endl;
  }
};

We can create a std::unique_ptr of type C. C is the class we defined here.

std::unique_ptr<C> pc = std::unique_ptr<C>(new C());

But we can not assign this unique_ptr, pc, to another unique_ptr.

std::unique_ptr<C> new_pc = pc;

This will produce a compilation error. But we can move the ownership of the actual pointer to new std::unique_ptr.

std::unique_ptr<C> new_pc = std::move(pc);

After this, pc will no longer own the actual pointer. We won’t be able to use the old unique_ptr, pc.

if(pc == nullptr) {
  std::cout << "pc does not own the actual pointer" << std::endl;
}

The pc == nullptr check will return true. But we’ll be able to use the new sunique_ptr, new_pc, and call the new_pc->f() function.

Passing std::unique_ptr to a Function

Similar thing happens if we try to pass a std::unique_ptr as a function parameter.

std::unique_ptr<C> func1(std::unique_ptr<C> ptr)
{
  ptr->f();
  return ptr;
}

The func1() takes a unique_ptr of type C.

std::unique_ptr<C> pc = std::unique_ptr<C>(new C());
func1(pc)

This will produce compilation errors. But we can move the pc to the function parameter.

std::unique_ptr ret = func1(std::move(pc));

After this, pc will no longer own the actual pointer.

But when a function returns a std::unique_ptr, the ownership is automatically transferred to the returned variable. In this example, after func1 returns, ret will own the actual pointer. We’ll be able to call ret->f() function.

Author: Srikanta

I write here to help the readers learn and understand computer programing, algorithms, networking, OS concepts etc. in a simple way. I have 20 years of working experience in computer networking and industrial automation.


If you also want to contribute, click here.

Leave a Reply

Your email address will not be published. Required fields are marked *

0
1
1
4
3
0