使用通用侵入式指针客户端进行引用计数
Reference counting with a generic intrusive pointer client
简介
Peter Weinhart描述了如何使用CRTP设计一个通用的intrusive_ptr基类,它可以如下使用:
class foo : intrusive_base<foo>
{
// foo-specific code.
};
这种方法施加了所有foo
对象都携带引用计数器的约束。假设我们有时按值保留foo
,并且只想在有指针时支付引用计数器的价格。例如,有时我们希望创建foo
实例并将它们四处移动,有时我们还希望在堆上分配foo
。
从概念上讲,该场景的正确机制是std::shared_ptr
。然而,在某些情况下,需要原始指针来调用侵入式指针,例如,当通过采用无效指针的C API传递指针时。在这种情况下,在将指针传递给不透明的API之前,将"ref"指针,在将其返回时,将"unref"指针。
要控制foo
,最好的方法可能是使用基于策略的实现,并拥有foo
的引用计数和基本版本。在不控制foo
的情况下,另一种设计将颠倒继承关系:
template <typename Base>
class intrusive : public Base
{
// ?
private:
std::atomic_size_t ref_count_;
};
typedef intrusive<foo> intrusive_foo;
// Assume boost::intrusive_ptr as intrusive pointer implementation
boost::intrusive_ptr<intrusive_foo> x = new intrusive_foo;
{
auto y = x; // Semantics: boost::intrusive_ptr_add_ref(x.get())
// At scope exit: boost::intrusive_ptr_release(x.get())
}
在上面提到的文章中,Peter说这样一个"[intrusive
]的通用实现将使用C++0x可变模板和完美的转发。"
问题
这样一个通用的intrusive
类的实现会是什么样子?我可以看到它可能受益于C++11继承构造函数,但我不清楚如何使用上述工具来实现intrusive
的主体。
使用make_shared
可以获得与侵入式指针相同的效率。
在这种情况下,将指针传递到不透明的API之前"ref"指针,并在将其返回时"unref"指针
正如其他人所说,您可以使用enable_shared_from_this
从原始指针获取shared_ptr
(只要系统中某个位置至少有一个shared_ptr
仍然拥有该对象)
但为了回答主要问题,我认为他的意思是使用可变模板和完美转发来定义构造函数,它看起来像:
template <typename Base>
class intrusive : public Base
{
template<typename... Args>
intrusive(Args&&... args)
: Base(std::forward<Args>(args)...), ref_count_(0)
{ }
这允许您使用任意数量的任何类型的参数来构造intrusive
,这些参数将被转发到Base
,因此您可以使用可用于构造Base
的任何参数来构造它。
另一种选择是使用C++11继承构造函数(在任何编译器AFAIK中都没有实现)
template <typename Base>
class intrusive : public Base
{
using Base::Base;
- "unknown ca"自生成的 CA、证书和客户端/服务器
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 使用调试/崩溃报告将应用程序部署到客户端
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 从服务器传输到客户端的消息不会出现
- OpenSSL TLS服务器-使用客户端证书白名单
- 当服务中的事件被触发时,如何将响应从服务发送回客户端?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 提升 Asio TCP 服务器 处理多个客户端
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何绑定 C++ gRPC 客户端的网络接口
- C++套接字客户端到 Python 服务器未创建连接
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 将相机数据从服务器实时流式传输到客户端
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- GRPC C++ TLS 客户端 grpc::SslCredentials() 方法不返回
- 使用通用侵入式指针客户端进行引用计数
- 如何从C++中的函数返回对象引用,以及如何从客户端调用该函数
- 正在为客户端/服务器编译项目[Linker error]未定义对的引用