maybe I misunderstood some aspects of smart pointers in c++, but after executing this code:
class cls
{
public:
class deleter
{
public:
const cls& obj;
deleter(const cls& c) : obj(c) {}
void operator()(int* num)
{
std::cout << "deleter was called" << std::endl;
if (num)
{
std::cout << "num in deleter: " << *num << std::endl;
if (*num == *obj.int_ptr)
{
std::cout << "equal " << *num << " = " << *obj.int_ptr << std::endl;
delete num;
}
else
std::cout << "not equal" << std::endl;
}
}
};
std::shared_ptr<int> int_ptr;
cls() : int_ptr(nullptr,deleter(*this)) {}
};
int main()
{
cls obj;
obj.int_ptr.reset(new int{15});
return 0;
}
Output:
deleter was called
0
I noticed that reset() from shared_ptr removes custom deleter, that was passed to it in its constructor. On the contrary unique_ptr doesn't show such behavior, which seemed strange to me.
So what is going on here?
When we assign the nullptr
or call reset on std::shared_ptr, it will clear the pointer and getdeleter after cleaning memory. The way it is done for unique_ptr is different.
Below is the function from library which decrement the count of shared_ptr and if reference_count is zero then proceed with destruction:
void _Decref() noexcept { // decrement use count
if (_MT_DECR(_Uses) == 0) {
_Destroy();
_Decwref();
}
}
So, once you reset and reference _count is zero then the shared_ptr the custom deleter will be removed due to reset.