我看到很多在C ++中使用PImpl惯用语的源代码。我假设它的目的是隐藏私有数据/类型/实现,因此它可以消除依赖关系,然后减少编译时间和标头包含问题。
但是C ++中的interface / pure-abstract类也具有此功能,它们也可以用于隐藏数据/类型/实现。为了让调用者在创建对象时只看到接口,我们可以在接口的头中声明一个工厂方法。
比较为:
费用:
接口方式的成本较低,因为您甚至不需要重复公共包装器函数的实现
void Bar::doWork() { return m_impl->doWork(); }
,您只需要在接口中定义签名即可。很好理解:
每个C ++开发人员都可以更好地理解接口技术。
性能:
接口方式的性能并不比PImpl成语差,两者都需要额外的内存访问。我认为性能是一样的。
以下是伪代码来说明我的问题:
// Forward declaration can help you avoid include BarImpl header, and those included in BarImpl header.
class BarImpl;
class Bar
{
public:
// public functions
void doWork();
private:
// You don't need to compile Bar.cpp after changing the implementation in BarImpl.cpp
BarImpl* m_impl;
};
可以使用接口实现相同的目的:
// Bar.h
class IBar
{
public:
virtual ~IBar(){}
// public functions
virtual void doWork() = 0;
};
// to only expose the interface instead of class name to caller
IBar* createObject();
那么PImpl有什么意义呢?
Impl
类中添加public函数不会中断ABI
,但是在接口中添加public函数会中断ABI
。