[CAT*G Translation Project GotW#22-30: Draft]
GotW #24 Compilation Firewalls
著者:Herb Sutter
翻译:CAT*G
[声明]:本文内容取自www.gotw.ca网站上的Guru of the Week栏目,其著作权归原著者本人所有。译者CAT*G在未经原著者本人同意的情况下翻译本文。本翻译内容仅供自学和参考用,请所有阅读过本文的人不要擅自转载、传播本翻译内容;下载本翻译内容的人请在阅读浏览后,立即删除其备份。译者CAT*G对违反上述两条原则的人不负任何责任。特此声明。
Revision 1.0
Guru of the Week 条款24:编译级防火墙
难度:6 / 10
(使用pimpl惯用法可以大大降低代码之间的相互依赖性,还可以减少程序的建立时间。但问题是,应该把那些东西放入pimpl对象里呢?如何才能安全的使用它呢?)
[Problem]
[问题]
在C++中,如果类定义中的任何部分被改变了(即使是私有成员),那么这个类所有的使用者代妈都必须重新编译。为了降低这种依赖性,使用的一种常见的技术就是利用一个不透明指针(opaque pointer)来隐藏一部分实现细节:
class X {
public:
/* ... 公有成员 ... */
protected:
/* ... 保护成员?... */
private:
/* ... 私有成员?... */
class XImpl* pimpl_; // 指向一个被前置声明了的(forward-declared)类
// 之不透明指针
};
[Questions]
[提问]
1.那些部分应该放入Ximpl?有四种常见的原则,它们是:
- 将全部私有数据(但不是函数)放入Ximpl;
- 将全部私有成员(译注:即包括函数)放入Ximpl;
- 将全部私有成员和保护成员放入Ximpl;
- 使Ximpl完全成为原来的X,将X编写为一个完全由简单的前置函数(forwarding functions)(一个句柄/本体的变体)组成的公共接口。
它们各有什么优缺点?你如何从中选择合适的?
2.Ximpl需要一个指向X对象的"反向指针(back pointer)"吗?
[Solution]
[解答]
首先看两个定义:
可见类(visible class):客户代吗所见并操纵的类(在这里即是X)。
pimpl:可见类中隐藏在一个透明指针(也称为pimpl_)下的类实现(在这里即是XImpl)。
在C++中,如果类定义中的任何部分被改变了(即使是私有成员),那么这个类所有的使用者代妈都必须重新编译。为了降低这种依赖性,使用的一种常见的技术就是利用一个不透明指针(opaque pointer)来隐藏一部分实现细节:
这是"句柄/本体"惯用法(handle/body idiom)的一种变体。如Coplien[注1]所记载,这种方法主要用于在共享代码的情况下进行引用计数(reference counting)。