Suppose I create a shared pointer with a custom deleter. In the following code I would like to check what happens with the deleter object itself:
struct A {
A() { std::cout << "A\n"; }
~A() { std::cout << "~A\n"; }
};
struct D {
D() {
std::cout << "D\n";
}
~D() {
std::cout << "~D\n";
}
D(const D&) {
std::cout << "D(D&)\n";
}
void operator()(A* p) const {
std::cout << "D(foo)\n";
delete p;
}
};
int main()
{
std::shared_ptr<A> p(new A, D());
}
I see that D(const D&)
and ~D()
for the "deleter" class are called six more times:
D
A
D(D&)
D(D&)
D(D&)
D(D&)
D(D&)
D(D&)
~D
~D
~D
~D
~D
~D
D(foo)
~A
~D
What happens? Why it needs to be copied so many times?
I checked your code with gcc 7.4 and I get the same number of calls to the destructors. What you observe is that the deleter object is moved six times through std::move(deleter)
.
As you have added a destructor to your class, the automatic generation of the default move semantics is disabled and you need to define them explicitly:
D(D&&) = default;
D& operator=(D&&) = default;
However, even with move semantics the destructor can still be called up to six times.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With