Destructor Call?

Write your question here.
Why is the Destructor called after the Move assignment operator?


Construction from repeated character
Move construction:
Contruction from a string.
goodbye
******************************
Move assignment:
Contruction from a string.
Move assignment operator.
Destructor.
toodlepip
******************************
Destructor.
Destructor.
Press any key to continue . . .




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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Soln8_04.cpp
// The only change required is to the assignment operator to check for lhs being the same as rhs
// To trace constructor and operator function calls, uncommenting the next line
#define TRACE

#include <iostream>                                        // For stream input/output
#include <cstring>

using std::cout;
using std::endl;

class CSimpleString
{
private:
	size_t len{};
	char* buff{};
public:
	CSimpleString(const char* p = nullptr);
	CSimpleString(const CSimpleString& s);
	CSimpleString(CSimpleString&& s);                        // Move copy constructor

	CSimpleString(char c, int count = 1);
	CSimpleString(int i);

	~CSimpleString();

	CSimpleString& operator=(const CSimpleString& rhs);     // Assignment operator
	CSimpleString& operator=(CSimpleString&& rhs);          // Move assignment operator
	void print();
};

// Contructor - repeated given character
CSimpleString::CSimpleString(char c, int count)
{
#ifdef TRACE
	cout << "Construction from repeated character\n";
#endif
	len = count;
	if (len)
	{
		buff = new char[len + 1];
		memset(buff, c, len);
		buff[len] = '\0';
	}
}

// Constructor - from an integer
CSimpleString::CSimpleString(int i)
{
#ifdef TRACE
	cout << "Contruction from an integer.\n";
#endif
	char sTmp[20];
	_itoa_s(i, sTmp, _countof(sTmp), 10);

	len = strlen(sTmp);
	if (len)
	{
		buff = new char[len + 1];
		strcpy_s(buff, len + 1, sTmp);
	}
}

// Constructor
CSimpleString::CSimpleString(const char* p)
{
#ifdef TRACE
	cout << "Contruction from a string.\n";
#endif
	if (p)
	{
		len = strlen(p);
		if (len)
		{
			buff = new char[len + 1];
			strcpy_s(buff, len + 1, p);
		}
	}
}

// Copy constructor
CSimpleString::CSimpleString(const CSimpleString& s)
{
#ifdef TRACE
	cout << "Copy constructor.\n";
#endif
	len = s.len + 1;
	buff = new char[len];
	strcpy_s(buff, len, s.buff);
}

// Move copy constructor
CSimpleString::CSimpleString(CSimpleString&& s)
{
#ifdef TRACE
	cout << "Move copy constructor.\n";
#endif
	len = s.len;
	buff = s.buff;
	s.buff = nullptr;                                        // Prevent the string from being deleted
}

// Destructor
CSimpleString::~CSimpleString()
{
#ifdef TRACE
	cout << "Destructor.\n";
#endif
	delete[] buff;
}

// Assignment operator - does deal with str = str
CSimpleString& CSimpleString::operator=(const CSimpleString& rhs)
{
#ifdef TRACE
	cout << "Assignment operator.\n";
#endif
	if (this != &rhs)
	{
		len = rhs.len + 1;
		delete buff;
		buff = new char[len];
		strcpy_s(buff, len, rhs.buff);
	}
	return *this;
}

// Move assignment operator
CSimpleString& CSimpleString::operator=(CSimpleString&& rhs)
{
#ifdef TRACE
	cout << "Move assignment operator.\n";
#endif
	len = rhs.len;
	buff = rhs.buff;
	rhs.buff = nullptr;
	return *this;
}

void CSimpleString::print()
{
	cout << buff;
}

int main()
{
	CSimpleString marker{ '*', 30 };
/*	CSimpleString s1{ "hello" };
	CSimpleString s2;

	// Test assignment
	marker.print();
	cout << endl;
	cout << "s1 is \"";
	s1.print();
	cout << "\" and s2 is empty.\n";

	s2 = s1;

	cout << " After s2 = s1, s2 is \"";
	s2.print();
	cout << endl;
	marker.print();
	cout << endl;

	// Test construction from an integer
	int n = 7890;

	CSimpleString nStr{ n };

	cout << n << " as a string is \"";
	nStr.print();
	cout << "\"" << endl;
	marker.print();
	cout << endl;
*/
	// Test move constructor
	cout << "Move construction:\n";
	CSimpleString s3{ CSimpleString{ "goodbye" } };
	s3.print();
	cout << endl;
	marker.print();
	cout << endl;

	// Test move assignment
	cout << "Move assignment:\n";
	s3 = CSimpleString{ "toodlepip" };
	s3.print();
	cout << endl;
	marker.print();
	cout << endl;
}
Because for every construction there should be corresponding destruction (or everything created should be destroyed).

On line 87 temporary is created, passed as argument to move assigment operator and after all operations with it are done, is destroyed.
Is the temporary CSimpleString{"toddlepip"}?
Yes. You even create it explicitely (s3 = "toodlepip"; should work the same in your case)
Thank you very much.
Topic archived. No new replies allowed.