pimpl呢,是privacy implement,隐藏内部实现的意思。
pimpl模式解决了隐藏实现的问题,在 gotw条款#28 中曾介绍过fastpimpl模式。 从编译开始说起吧,每个cpp文件都会作为一个编译单元,,送交编译器进行编译,而头文件(.h,.hpp)是不会单独编译的,仅会被cpp文件包含进去一起编译。 ok,我们这时候有两个类:class BrowserWindow和class AddressBar。 BrowserWindow做为一个浏览器窗口 class BrowserWindow{ 我们知道 setUrl是BrowserWindow向外提供的接口,这是BrowserWindow类的使用者(cpp文件)关心的。 而m_addressBar则是BrowserWindow的实现所用到的内部数据成员,,使用者不关心。 BrowserWindow的接口改变了,,BrowserWindow的使用者(其他cpp文件)都要重新编译,,因为其他使用了BrowserWindow类的cpp文件,,依赖于BrowserWindow的接口。 但是BrowserWindow的实现改变了,,只需要重新编译browserwindow.cpp就可以了,,其他cpp文件则不需要重新编译。 ok, 以上说的这些,使我们所期待看到的,,因为我们可不希望某个类的实现改变了,,其他100个依赖该类的cpp文件都要重新编译一遍,,那可能是一杯咖啡,,或者一支烟的时间。 但是,,AddressBar这个类的定义改变的时候,,BrowserWindow却要重新编译,,从而导致所有依赖BrowserWindow的cpp文件也全部被重新编译了。 这是为什么呢? 因为我们知道:AddressBar *m_addressBar = new AddressBar 的本质是: AddressBar m_addressBar; 的本质是 而sizeof(AddressBar),,会在编译中被替换为一个具体的数值。 所以,如果AddressBar的定义改变了,,sizeof(AddressBar)得到的具体数值就会改变。 从而导致,,在实际编译时,BrowserWindow.h头文件改变。 因为AddressBar结构的改变,导致BrowserWindow的改变,,最终导致所有new BrowserWindow和BrowserWindow m_bw的BrowserWindow的使用者改变。 (因为无论是new,还是直接在栈上声明,,最终都会替换为sizeof(BrowserWindow) ) 所以,我们改成前向声明的方式: class AddressBar; ok,上面是以addressBar来说明的,,其实可以用一个BrowserWindowImpl类,来封装所有的实现。 class BrowserWindowImpl; 而在BrowserWindowImpl中,定义AddressBar,无论是直接定义AddressBar的实例还是指针,都不会引起BrowserWindow的重新编译,也不会引起使用BrowserWindow的cpp模块的重新编译。 原文地址:点击打开链接 |
pimpl
最新推荐文章于 2024-08-17 19:50:43 发布