考虑以下几点:
PImpl.hpp
class Impl;
class PImpl
{
Impl* pimpl;
PImpl() : pimpl(new Impl) { }
~PImpl() { delete pimpl; }
void DoSomething();
};
PImpl.cpp
#include "PImpl.hpp"
#include "Impl.hpp"
void PImpl::DoSomething() { pimpl->DoSomething(); }
实现.hpp
class Impl
{
int data;
public:
void DoSomething() {}
}
客户端.cpp
#include "Pimpl.hpp"
int main()
{
PImpl unitUnderTest;
unitUnderTest.DoSomething();
}
此模式背后的想法是Impl
的接口(interface)可以更改,但不必重新编译客户端。然而,我看不出这是怎么回事。假设我想向此类添加一个方法——客户端仍然必须重新编译。
基本上,我曾经看到的唯一需要更改类的头文件的更改是类接口(interface)更改的内容。当发生这种情况时,无论是否有 pimpl,客户端都必须重新编译。
在不重新编译客户端代码方面,这里的哪些类型的编辑给我们带来了好处?
最佳答案
主要优点是接口(interface)的客户端不必包含所有类的内部依赖项的 header 。因此,对这些 header 的任何更改都不会级联到对大部分项目的重新编译中。加上关于实现隐藏的一般理想主义。
此外,您不必将 impl 类放在它自己的标题中。只需将其作为单个 cpp 内的结构,并让您的外部类直接引用其数据成员即可。
编辑:示例
一些类.h
struct SomeClassImpl;
class SomeClass {
SomeClassImpl * pImpl;
public:
SomeClass();
~SomeClass();
int DoSomething();
};
一些类.cpp
#include "SomeClass.h"
#include "OtherClass.h"
#include <vector>
struct SomeClassImpl {
int foo;
std::vector<OtherClass> otherClassVec; //users of SomeClass don't need to know anything about OtherClass, or include its header.
};
SomeClass::SomeClass() { pImpl = new SomeClassImpl; }
SomeClass::~SomeClass() { delete pImpl; }
int SomeClass::DoSomething() {
pImpl->otherClassVec.push_back(0);
return pImpl->otherClassVec.size();
}
关于c++ - pimpl 习语如何减少依赖性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3597693/