用C++处理身体习语
Handle Body Idiom in C++
我的库中有一个类,我想向用户公开它。我不想公开整个类,因为我以后可能想进行二进制不兼容的更改。我不知道以下哪种方式最好。
案例1:
struct Impl1;
struct Handle1
{
// The definition will not be inline and will be defined in a C file
// Showing here for simplicity
void interface()
{
static_cast<Impl1*>(this)->interface();
}
}
struct Impl1 : public Handle1
{
void interface(){ /* Do ***actual*** work */ }
private:
int _data; // And other private data
};
案例2:
struct Impl2
struct Handle2
{
// Constructor/destructor to manage impl
void interface() // Will not be inline as above.
{
_impl->interface();
}
private:
Impl2* _impl;
}
struct Impl2
{
void interface(){ /* Do ***actual*** work */ }
private:
int _data; // And other private data
};
Handle类仅用于公开功能。它们将仅在库中创建和管理。继承只是为了抽象实现细节。不会有多个/不同的impl类。就性能而言,我认为两者将完全相同。是吗?我正在考虑采用案例1的方法。有什么问题需要解决吗?
您的第二种方法看起来非常像编译防火墙习惯用法(有时称为PIMPL习惯用法)。
唯一的区别是,在编译防火墙习惯用法中,实现类通常(但并不总是)被定义为成员。别忘了构造函数(分配Impl)和析构函数(释放它)。以及复制构造函数和赋值运算符。
第一种方法也适用,但它需要工厂函数来创建对象。当我使用它时,我只需将Handle
中的所有函数都设置为纯虚拟函数,并让客户端代码直接调用它们。
在这种情况下,由于客户端代码实际上有指向对象的指针(在编译防火墙习惯用法中,唯一的指针在Handle
类本身中),客户端将不得不担心内存管理;如果没有循环是可能的,这是shared_ptr
非常有意义的一种情况。(出厂功能可以返回例如,shared_ptr
和客户端代码可能永远看不到原始指针。)
相关文章:
- 概念可以与 CRTP 习语一起使用吗?
- 复制和交换习语和迭代器
- 为什么当我做复制和交换习语时不调用我的复制构造函数?
- 漂亮的计数器习语的错误或格式错误的静态订单惨败?
- C++17 pimpl 习语上下文中的自定义迭代器
- 在 MyVector 中实现写入时复制习语
- 视觉 "extern __forceinline "是什么 c++ 习语?
- C 习语使用C库时,该C库期望功能指针
- 为什么 std::swap 不使用 swap 习语?
- 如何使用擦除删除习语从结构向量中删除值
- C++中的Singleton习语
- 在 C++11 中实现复制和交换习语的更好方法
- N 个并发读取器和 1 个生产者的习语或模式
- pImpl习语-将私有类实现放在cpp中有什么缺点
- 不能使用 pimpl 习语将用户定义的向量插入到封装的向量中
- Python -> C++ 习语:将 lambda 表达式存储在映射/容器中
- 安全方便的通用散列(用于 STL 无序集和映射)习语?
- 指向可配置实现的Pimpl习语
- 用C++处理身体习语
- 使用shared_ptr处理不完全类型的Pimpl习语