c++ - pimpl 习语如何减少依赖性?

标签 c++ pimpl-idiom

考虑以下几点:

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/

相关文章:

c++ - 在不移动光标的情况下模拟鼠标点击

c++ - 与 Libxml2 中的 selectSingleNode 类似的功能?

c++ - C++ 编译器是为所有成员方法生成 "this"指针,还是只为引用成员的方法生成指针?

c++ - 使用 Pimpl 的高级变体时可能会影响性能?

c++ - 粉刺 : Avoiding pointer to pointer with pimpl

c++ - 在运行时在 C++ 中创建静态数组

c++ - 具有类型名称的矩阵总和

c++ - PIMPL 和堆栈分配

c++ - 使用 pimpl 习惯用法时如何创建私有(private)静态常量字符串

C++ 嵌套类 - 将实现移动到不同的文件