By disabling copy constructor and copy assignment, we can be sure that the ownership of B is “moved” from one owner to another.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <memory>
using namespace std;

struct B {
~B() {
puts("~B");
}
};


struct A {
unique_ptr<B> o;

A() {}

explicit A(B* o_) : o{o_} {}

A(const A&) = delete;
A& operator=(const A&) = delete;

A(A&& other) : o{move(other.o)} {
puts("move ctor");
}

A& operator=(A&& other) {
puts("move =");
o = move(other.o);
return *this;
}
};

int main()
{
{
A a1{new B};
printf("a1.o is %p\n", a1.o.get());
// A a2 = a1; // error; deleted copy ctor
}

puts("");

{
A a1{new B};
printf("a1.o is %p\n", a1.o.get());
// A copied = a1; // error; deleted copy ctor
A a2 = move(a1);
printf("a1.o is %p\n", a1.o.get());
}

puts("");

{
A a1{new B};
printf("a1.o is %p\n", a1.o.get());
A a2{move(a1)};
printf("a1.o is %p\n", a1.o.get());
}

puts("");

{
A a1{new B};
printf("a1.o is %p\n", a1.o.get());
A a2;
a2 = move(a1);
printf("a1.o is %p\n", a1.o.get());
}

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ clang++ -std=c++11 -stdlib=libc++ test.cc && ./a.out
a1.o is 0x189cc20
~B

a1.o is 0x189cc20
move ctor
a1.o is (nil)
~B

a1.o is 0x189cc20
move ctor
a1.o is (nil)
~B

a1.o is 0x189cc20
move =
a1.o is (nil)
~B