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.