C++中的句柄类
Handle class in C++?
在C++引物15.8中,当作者谈到"处理类和继承"时,他说:
C++中的一种常见技术是定义一个所谓的cover或handle类。句柄类存储并管理指向基类的指针。指针指向的对象的类型会有所不同;它可以指向基类型对象或派生类型对象。用户通过句柄访问继承层次结构的操作。由于句柄使用其指针来执行这些操作,因此虚拟成员的行为在运行时会因句柄实际绑定到的对象类型而异。句柄的用户因此获得了动态行为,但他们自己不必担心管理指针。
对我来说,上面听起来很像一个智能指针。然而,这个"句柄"的用法有点不同。
Handle h(Derived()); // noticed a derived object, not a pointer is used to initialize the handle!
h->func();
句柄的后一个实现(如下所示)证明了作者对句柄的评论:
我们希望我们的句柄的用户创建他们自己的对象,他们可以将句柄附加到该对象句柄将分配一个适当类型的新对象,并将用户的对象复制到新分配的对象中。这样,句柄类将拥有对象,并可以保证在附加到对象的最后一个句柄消失之前不会删除该对象。
代码:
public:
Base(){}
virtual int func(std::size_t n) const {}
virtual Base* clone() const { return new Base(*this); }
};
class Derived : public Base {
public:
Derived():Base(){}
int func(std::size_t) const; // redefine
Derived* clone() const { return new Derived(*this); }
};
class Handle {
public:
Handle(const Base &b):p(b.clone()), use(new std::size_t(1)) { }
private:
Base *p;
std::size_t *use; // pointer to shared use count
};
我的问题是:这真的是C++或OO中句柄的典型含义吗?我认为句柄可以只是一个在内部保持使用计数的基类型智能指针,或者更一般地说,是一些系统知道它指向什么以及如何处理它的神奇int类型。为什么这个句柄需要将用户对象复制到自己身上,然后根据副本使用计数?
现代C++中惯用的等价物是:
std::shared_ptr<Base> h{std::make_shared<Derived>()};
通常,"句柄"意味着某种形式的类型擦除,因此处理句柄的代码不需要知道如何实现功能的细节。
您显示的代码使用clone
复制对象的原因正是为了执行类型擦除;在CCD_ 2方法被称为CCD_。就实现质量而言,代码是非线程安全的,这与传统C++无关,但对现代C++来说是一个问题,因为现代C++确实有线程感知内存模型。它显然也不是例外安全;将异常安全性委托给像shared_ptr
这样的标准库类要好得多。最后,Base
类缺少一个虚拟析构函数。
- 外壳包装器句柄/执行交互式命令管道C++ UNIX
- 如何获取边缘窗口句柄 (HWND)?
- 枚举进程模块在有效句柄上返回无效句柄
- 在 c/c++ 中打开 PhysicalDrive 的句柄并写入 MBR 的 linux 等效是什么?
- 从运行服务的应用程序代码中提取窗口句柄
- 在读取文件后重置句柄
- 是否有像地图这样的C++结构,但我得到的不是值的键,而是值的句柄?
- Microsoft ODBC 无法创建有效的句柄
- 我是否可以使用 win32 句柄以编程方式记录发送到/接收到 USB/COM 的内容
- 获取特定进程的句柄数
- C++ 创建 NdisProt 驱动程序的句柄
- 是否需要关闭来自 WinHTTP 异步的句柄?
- 句柄OK全部崩溃
- 我需要通过窗口句柄(HWND)获取文件,我该怎么办?
- 什么是 C# 等同于C++句柄
- 未知C++错误:致命错误:glibc检测到无效的stdio句柄
- 获取现有进程句柄
- GetModuleHandle() 无法检索由 "notepad.exe" 加载的"advapi32.dll"的句柄
- 更正GLSL无绑定纹理句柄中的结构布局
- 带有资源句柄的TensorFlow自定义C++操作