这里是table.h
提取的代码片段,并从table_builder.h
一个代码片断将都表现出了类似的设计
class Table
{
...
struct Rep;
Rep* rep_;
...
};
因此,你想出的解释是正确的之一:
- 类
table.h
的声明和table_builder.h
暴露于leveldb
客户;
- 但是,设计者不想公开数据的内部表示,因为它们是实现细节,在接口中是不必要的;
- 因此,这些细节已被移出到单独的结构中,结构
Rep
在公共接口(头文件)中声明,但仅在实现文件(源文件)中定义和使用;
- 这是一个相当常见的习惯用法,通常称为pImpl idiom(因为指向实施通常被称为
pImpl
)或compilation firewall。
除了设计封装外,这个习语还有另一个原因,这是可用性。事实上,如果Table
的内部细节暴露在Table.h
中,则每次这些细节更改时,包含Table.h
的任何leveldb用户源文件都必须重新编译。
通过隐藏这些实现细节,leveldb用户的源文件不受leveldb数据内部表示的更改影响。只要leveldb公共接口(公共头文件)不更改,用户就可以从一个版本的leveldb升级到另一个版本,而无需重新编译它们的源代码:它们只需要链接到新版本的leveldb库。因此,这个习惯用法对于图书馆开发者来说是非常重要的,并且也可以用来最小化程序的不同模块之间的耦合。