If I run the code
class Myc {
private:
int m{0};
public:
Myc(int ii) : m{ii} {};
~Myc() { std::cout << "Myc Destructed\n"; }
int getM() const { return m; }
};
void foo(std::unique_ptr<Myc> other) { std::cout << "End foo\n"; }
int main() {
std::unique_ptr<Myc> pm = std::make_unique<Myc>(1);
foo(std::move(pm));
std::cout << "End main \n";
}
the ownership of pm is transfered to foo and the output is
End foo
Myc Destructed
End main
but if change foo to
void foo(std::unique_ptr<Myc> &&other) { std::cout << "End foo\n"; }
the ownership of pm is NOT transfered to foo because the output is
End foo
End main
Myc Destructed
I have tried this in clang and gcc. Why the ownership of pm is NOT transfered to foo when using rvalue reference?
Pass unique_ptr
(or any smart pointer) by value when you want to transfer ownership.
Passing one by reference doesn't change ownership, and if the function doesn't change the ownership, perhaps it doesn't need a smart pointer as an argument (a bare pointer is often better).
To answer your question more directly: when you pass by value, the formal parameter (other
) is move-constructed from the actual parameter. The move constructor is what transfers ownership. When you pass by reference, however, the formal parameter is a reference to the existing object - no new object is created, so the move constructor never happens.