aboutsummaryrefslogtreecommitdiff
path: root/raii/all-constructors.cpp
blob: 27add071d4ea7bb335e29c702ad6913a1992826f (plain)
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <iostream>

class T {
public:
	T(const std::string& a) : name{a} {
		std::cout << "Called constructor for " << name
		          << " (" << this << ")" << std::endl;
	}

	~T() {
		std::cout << "Called destructor for " << name
		          << " (" << this << ")" << std::endl;
	}

	T(T& other) : name{other.name} {
		std::cout << "Copy constructor called for " << name
		          << " (" << this << " copied from "
		          << &other << ")" << std::endl;
	}

	T& operator=(T& other) {
		name = other.name;
		std::cout << "Copy assignment called for " << name
		          << " (" << this << " copied from "
		          << &other << ")" << std::endl;
		return *this;
	}

	T(T&& other) : name{other.name} {
		std::cout << "Move constructor called for " << name
		          << " (" << this << " moved from "
		          << &other << ")" << std::endl;
	}

	T& operator=(T&& other) {
		name = other.name;
		std::cout << "Move assignment called for " << name
		          << " (" << this << " moved from "
		          << &other << ")" << std::endl;
		return *this;
	}
private:
	std::string name;
};

T do_nothing_and_return(T x) {
	return x;
}

T create(const std::string& str) {
	return T(str);
}

int main() {
	//T bad; // Compile-time error: no default constructor.

	std::cout << "---------- Declaring a simple variable ----------" << std::endl;
	T a("A");
	std::cout << std::endl;

	// Now we can see that objects are indeed scope-bound: they
	// are destroyed when they go out of scope.
	std::cout << "--- Declaring a variable in a temporary scope ---" << std::endl;
	{
		std::cout << "Entering temporary scope" << std::endl;
		T b("short-lived");
		std::cout << "Exiting temporary scope" << std::endl;
	}
	std::cout << "Out of temporary scope" << std::endl;
	std::cout << std::endl;

	std::cout << "------------ Constructing by copying ------------" << std::endl;
	T b("B");
	T c(b);
	T d = b; // This is also a copy constructor, not a copy assignment
	std::cout << std::endl;

	// Copy assignment operators differ from copy constructors in that they
	// should also clean up the resources for the copied-to object.
	std::cout << "---------------- Copy assignment ----------------" << std::endl;
	c = b;
	std::cout << std::endl;

	std::cout << "------------ Constructing by moving -------------" << std::endl;
	T e(do_nothing_and_return(b));
	std::cout << std::endl;

	std::cout << "---------------- Move assignment ----------------" << std::endl;
	e = create("E");
	std::cout << std::endl;
	
	std::cout << "------------- Destroying everything -------------" << std::endl;
	return 0;
}

Generated with cgit - Back to sebastiano.tronto.net