问题
I could not find (of the many questions on destructor calling topics) any that were exactly the same as my situation.
Why is the destructor being called when the parameter passed is a reference? I put comments (mostly in main) under the lines of code where I thought the output was executing from.
struct X { // simple test class
int val;
void out(const std::string& s, int nv)
{
std::cerr << this << "–>" << s << ": " << val << " (" << nv << ")\n";
}
// default constructor
X() {
out("X()", 0);
val = 0;
}
X(int v) {
val = v;
out("X(int)", v);
}
// copy constructor
X(const X& x) {
val = x.val;
out("X(X&) ", x.val);
}
// copy assignment
X& operator=(const X& a)
{
out("X::operator=()", a.val);
val = a.val;
return *this;
}
// Destructor
~X() {
out("~X()", 0);
}
};
X glob(2); // a global variable
// Output Line 1: X(int): 2 (2)
X copy(X a) {
return a;
}
main
Function:
int main()
{
X loc{ 4 }; // local variable
// Output Line 2: X(int): 4 (4)
// ^from X(int v) function
X loc2{ loc }; // copy construction
// Output Line 3: X(X&) : 4 (4)
// ^from X(const X& x) function
loc = X{ 5 }; // copy assignment
// Output Line 4: X(int): 5 (5)
// ^from X(int v) function
// Output Line 5: X::operator=(): 4 (5)
// ^from the '=' operator overload
// Output Line 6: ~X(): 5 (0) - ???
loc2 = copy(loc); // call by value and return
// Or does Output Line 6 result from here?
.
.
.
}
1) Is this destructor is being called because of loc = X{ 5 }; // copy assignment
or the line after: loc2 = copy(loc); // call by value and return
?
2) Why is it being called? From what I've read, destructors are only called when:
a) names go out of scope
b) program terminates
c) "delete" is used on a pointer to an object
I know its not 'b' or 'c' so it has to be because something is going out of scope. But I do not think a reference going out of scope from the copy assignment function does this.
回答1:
You can see that the destructor is called soon after the copy assignment has taken place. After the copy assignment is complete, the temporary (x{5}
) is destroyed.
From the standard's section on destructors:
15.4 Destructors
...
12. A destructor is invoked implicitly
(12.1) — for a constructed object with static storage duration at program termination,
(12.2) — for a constructed object with thread storage duration at thread exit,
(12.3) — for a constructed object with automatic storage duration when the block in which an object is created exits,
(12.4) — for a constructed temporary object when its lifetime ends.
来源:https://stackoverflow.com/questions/53007375/passing-by-reference-why-is-this-destructor-being-called