那么,我想知道这种技术真的在实践中得到应用吗?我应该在任何地方使用它还是谨慎使用?
当然是用的。我在我的项目中,几乎在每堂课上都使用它。
使用 PIMPL 习惯用法的原因:
二进制兼容性
当您开发库时,您可以添加/修改字段XImpl
不会破坏与客户端的二进制兼容性(这意味着崩溃!)。由于二进制布局X
当您添加新字段时,类不会改变Ximpl
类,在次要版本更新中向库添加新功能是安全的。
当然,你也可以添加新的公共/私有非虚拟方法X
/XImpl
不会破坏二进制兼容性,但这与标准标头/实现技术相当。
数据隐藏
如果您正在开发一个库,尤其是一个专有库,那么最好不要透露使用了哪些其他库/实现技术来实现您的库的公共接口。要么是因为知识产权问题,要么是因为您认为用户可能会对实现做出危险的假设,或者只是通过使用可怕的转换技巧来破坏封装。 PIMPL 解决/缓解了这个问题。
编译时间
编译时间减少,因为只有源(实现)文件X
当您添加/删除字段和/或方法时需要重建XImpl
类(映射到在标准技术中添加私有字段/方法)。实际上,这是一个常见的操作。
使用标准标头/实现技术(无 PIMPL),当您向X
,每个分配过的客户X
(无论是在堆栈上,还是在堆上)需要重新编译,因为它必须调整分配的大小。好吧,每个不分配 X 的客户端also需要重新编译,但这只是开销(客户端的结果代码将是相同的)。
更重要的是,通过标准头文件/实现分离XClient1.cpp
即使是私有方法也需要重新编译X::foo()
被添加到X
and X.h
改变了,尽管XClient1.cpp
由于封装原因不可能调用此方法!如上所述,它是纯粹的开销,并且与现实生活中的 C++ 构建系统的工作方式有关。
当然,当您只修改方法的实现时,不需要重新编译(因为您没有触及标头),但这与标准标头/实现技术相同。
是否建议在嵌入式系统(性能非常重要)中使用该技术?
这取决于你的目标有多强大。然而,这个问题的唯一答案是:衡量和评估你的所得和失去。另外,请考虑到,如果您不发布供客户在嵌入式系统中使用的库,则只有编译时间优势适用!