重置 std::shared_ptr 会导致重置其删除器吗?
Does resetting std::shared_ptr lead to resetting its deleter?
也许我误解了 c++ 中智能指针的某些方面,但在执行此代码后:
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;
}
输出:
deleter was called
0
我注意到 reset(( 从 shared_ptr 中删除了在其构造函数中传递给它的自定义删除器。相反,unique_ptr没有表现出这样的行为,这对我来说似乎很奇怪。
这到底是怎么回事呢?
std::shared_ptr
将删除程序存储在控制块中。因此,您可以切换删除程序并将std::shared_ptr
与各种删除程序一起使用,同时与指向相同数据的所有其他std::shared_ptr
实例共享它。
std::unique_ptr
不需要任何此类内容,并在必要时将删除程序存储在其实例中。此外,您还必须将删除器的用法指定为模板参数之一。
基本上,在std::shared_ptr
删除器是数据的一部分,std::unique_ptr
删除器是类的一部分。
当我们在 std::shared_ptr 上分配nullptr
或调用重置时,它将在清理内存后清除指针和 getdeleter。unique_ptr的方式是不同的。
下面是库中的函数,它递减shared_ptr计数,如果reference_count为零,则继续销毁:
void _Decref() noexcept { // decrement use count
if (_MT_DECR(_Uses) == 0) {
_Destroy();
_Decwref();
}
}
因此,一旦重置并且引用_count为零,则自定义删除程序shared_ptr将因重置而被删除。
删除程序在 std::shared_ptr 中的存储方式与在 std::unique_ptr 中的存储方式不同。std::unique_ptr 使用空基优化 (EBO( 来存储删除程序,这意味着 std::unique_ptr 继承了删除程序。std::shared_ptr 不这样做,这就是删除程序 API 在两者之间不同的原因。
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- C++中的线程安全删除
- 如何从存储在std::映射中的std::集中删除元素
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数