shared_ptr如何存储deleter
How does a shared_ptr store deleter?
我不明白shared_ptr
如何存储我给它的deleter。
最初,使用shared_ptr<int>
时,我认为它可能使用std::function<void(int*)>
,但作为deleter,我可以给出任何类型的函数(或可调用对象),只要第一个参数是int*
。
shared_ptr
如何做到这一点?
如果这是一个愚蠢的问题,我很抱歉,我是C++的新手,请原谅!
编辑:问题是:我怎么能做这样的事?我应该用什么?有什么例子吗?或者这是一个非常高级的话题?
删除程序和分配器都是类型擦除的。共享指针管理一个动态分配的、私有的、模板化的控制对象,该对象通过多态库进行访问,并存储所有类型特定的状态和功能。
std::function
的实现使用了类似的思想,因为它也是一个类型擦除动态管理器类,但两者通常完全独立实现。
结果是,这两个类都相对"昂贵",只有在真正必要的时候才应该使用。否则,更便宜的、非多态的非动态解决方案通常更可取。
作为一个deleter,我可以给出任何类型的函数(或可调用对象),只要第一个参数是
int*
。
不,不是真的。std::shared_ptr
构造函数具有以下合同,见第20.8.2.2.1节([util.smartptr.shared.const]
):
template<class Y, class D> shared_ptr(Y* p, D d); template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); template <class D> shared_ptr(nullptr_t p, D d); template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
要求:
p
应可转换为T*
。D
应为可复制结构。D
的复制构造函数和析构函数不应抛出异常表达式d(p)
应格式良好,应具有定义良好的行为,并且不应抛出异常。A应该是一个分配器(17.6.3.5)。A的复制构造函数和析构函数不应该抛出异常。效果:构造一个
shared_ptr
对象,该对象拥有对象p
和deleterd
。第二个和第四个构造函数应使用a
的副本来分配内存供内部使用。后置条件:
use_count() == 1 && get() == p
。当无法获取内存以外的资源时,抛出:
bad_alloc
,或实现定义的异常。异常安全:如果抛出异常,则调用
d(p)
。
这个要求比deleter的第一个参数必须是正确的类型强得多。它必须是唯一的参数(没有默认参数),这样d(p)
才是合法的。这比std::function<void (int*)>
稍微灵活一些,因为返回类型可以是任何类型,但在异常保证方面也更受约束。
如果编译器在为deleter提供多个必需参数时没有发现问题,那么标准库实现就大错特错了。
至于如何实现它,请利用它必须是可复制可构造的这一事实。例如,以下lambda应该工作得很好,并且可以分配给std::function<void(void)>
(CopyConstructable保证确保按值捕获有效):
[d, p] { d(p); }
- 将字符串存储在c++中的稳定内存中
- std::原子加载和存储都需要吗
- C++:将控制台输出存储在宏中更好吗
- 使用QProcess执行命令,并将结果存储在QStringList中
- 访问存储在向量C++中的结构的多态成员
- 如何从存储在std::映射中的std::集中删除元素
- 存储模板类型以强制转换回派生<T>
- 类型总是使用其大小存储在内存中吗
- 当字符串存储在变量中时,如何将字符串转换为wchar_t
- 使用无符号字符数组有效存储内存
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 带结构的二维矢量:如何存储元素
- 添加存储在向量中的大整数的函数出现问题
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 在std::vector上存储带有模板的类实例
- 谷歌测试中的期望值存储在哪里
- 为什么C中的通用链表中存储的数据已损坏
- 在c++中获取两个大int,并将它们存储在数组中
- shared_ptr如何存储deleter