Lifetime
Inspired by one of Jason Turner’s videos I decided to create my own class that helps me better understand how objects behave in C++.
The implementation of such a class is quite simple - we just log information inside each of the special member functions, describing what is happening (constructors of various kinds, copy/move assignment operators and destructor).
For readability I decided to add a member to the class which we can set during object creation - it makes the console output much easier to follow.
Below is the implementation of the Lifetime object along with a few simple usage examples.
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
struct Lifetime
{
Lifetime() : name("for_default_constructor")
{
std::cout << "Lifetime(): " << name << std::endl;
}
Lifetime(const std::string& name) : name(name)
{
std::cout << "Lifetime(const std::string&): " << name << std::endl;
}
Lifetime(const Lifetime& other) : name(other.name)
{
std::cout << "Lifetime(const Lifetime&): " << name << std::endl;
}
Lifetime(Lifetime&& other) noexcept : name(std::move(other.name))
{
std::cout << "Lifetime(Lifetime&&): " << name << std::endl;
}
Lifetime& operator=(const Lifetime& other)
{
name = other.name;
std::cout << "operator=(const Lifetime&): " << name << std::endl;
return *this;
}
Lifetime& operator=(Lifetime&& other) noexcept
{
name = std::move(other.name);
std::cout << "operator=(Lifetime&&): " << name << std::endl;
return *this;
}
~Lifetime()
{
std::cout << "~Lifetime(): " << name << std::endl;
}
std::string name;
};
int main()
{
Lifetime lifetime1("lifetime1");
Lifetime lifetime2("lifetime2");
Lifetime lifetime3("lifetime3");
lifetime2 = lifetime1;
Lifetime lifetime4("lifetime4");
lifetime3 = std::move(lifetime4);
Lifetime lifetime5(Lifetime("lifetime4"));
return 0;
}
Below is the output produced by the program.
1
2
3
4
5
6
7
8
9
10
11
12
Lifetime(const std::string&): lifetime1
Lifetime(const std::string&): lifetime2
Lifetime(const std::string&): lifetime3
operator=(const Lifetime&): lifetime1
Lifetime(const std::string&): lifetime4
operator=(Lifetime&&): lifetime4
Lifetime(const std::string&): lifetime4
~Lifetime(): lifetime4
~Lifetime():
~Lifetime(): lifetime4
~Lifetime(): lifetime1
~Lifetime(): lifetime1
These are very simple examples, but once you start using this class in more advanced scenarios you’ll notice that it’s a really simple yet very effective way to better understand object lifetimes in C++.