• 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;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    示例

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

    Car.h

    #include 
    class CarImpl;
    
    class Car {
    public:
        Car();
        ~Car();
        void Start();
        void Stop();
      
    private:
        std::unique_ptr<CarImpl> pimpl;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

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

    总结

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

  • 相关阅读:
    LVM 镜像卷配置与维护
    explain的执行结果:Impossible WHERE
    [GIT]版本控制工具
    string类
    【Windows】搭建 FTP 服务器
    基于SSM的大学生创新创业平台竞赛管理子系统设计与实现
    pytest---添加自定义命令行参数(pytest_addoption )
    2022年最新《Java八股文面试宝典》全网独一份!(效率最高、知识最新、包含各个技术栈)
    初学kotlin 01
    wath修改data中的值后更新
  • 原文地址:https://blog.csdn.net/qq_42896106/article/details/132588949