C++ 中的 Pimpl 惯用法

C++ 中的 Pimpl 惯用法

介绍

Pimpl(Pointer to Implementation)是一种常见的 C++ 设计模式,用于隐藏类的实现细节,从而减少编译依赖和提高编译速度。本文将通过一个较为复杂的例子,展示如何使用智能指针(如 std::unique_ptr)来实现 Pimpl 惯用法。

什么是 Pimpl 惯用法?

Pimpl 是 “Pointer to Implementation” 的缩写,这个模式可以帮助我们:

  • 将接口和实现分离
  • 减少头文件中的依赖
  • 加速编译

基本实现

基本的 Pimpl 实现需要一个前置声明的内部类和一个指向该内部类的指针。在这里,我们使用 std::unique_ptr 来管理这个内部类的实例。

MyClass.h

#include 

class MyClassImpl; // 前置声明

class MyClass {
public:
    MyClass();
    ~MyClass();
    void DoSomething();

private:
    std::unique_ptr<MyClassImpl> pimpl;
};

MyClass.cpp

#include "MyClass.h"

class MyClassImpl {
public:
    void DoSomething() {
        // 实现细节
    }
};

MyClass::MyClass() : pimpl(std::make_unique<MyClassImpl>()) {}
MyClass::~MyClass() = default;

void MyClass::DoSomething() {
    pimpl->DoSomething();
}

示例

假设我们有一个 Car 类,它有多个组件,如 EngineWheel

Car.h

#include 
class CarImpl;

class Car {
public:
    Car();
    ~Car();
    void Start();
    void Stop();
  
private:
    std::unique_ptr<CarImpl> pimpl;
};

Car.cpp

#include "Car.h"
#include "Engine.h"
#include "Wheel.h"

class CarImpl {
public:
    Engine engine;
    Wheel wheel[4];

    void Start() {
        engine.Start();
        // 其他逻辑
    }
    void Stop() {
        engine.Stop();
        // 其他逻辑
    }
};

Car::Car() : pimpl(std::make_unique<CarImpl>()) {}
Car::~Car() = default;

void Car::Start() {
    pimpl->Start();
}

void Car::Stop() {
    pimpl->Stop();
}

在这个例子中,Car 的用户只需要包含 Car.h,而不需要知道 EngineWheel 的存在。这样就降低了编译依赖并提高了编译速度。

总结

通过使用 Pimpl 惯用法和智能指针,我们能更有效地隐藏实现细节,提高编译速度,并使代码更易于维护。

你可能感兴趣的:(c++)