C/C++|Pimpl Idiom(Pointer to IMPLementation) 指针实现模式浅析

Pimpl Idiom(Pointer to IMPLementation),也称为 "Opaque Pointer"(不透明指针)或 "Cheshire Cat"(柴郡猫)模式或者"指针实现模式"和"实现隐藏模式"。这种模式通过将类的实现细节放在一个单独的私有结构体中,并通过指针来访问,从而在不改变类接口的情况下,允许类的实现独立于类的定义进行修改和编译

文章目录

Pimpl Idiom 的基本思想

Pimpl Idiom 的核心思想是将类的实现细节放在一个私有的实现类中,并使用指向该实现类的指针在公共接口类中进行引用。这种方式可以将类的实现细节完全隐藏在实现文件中,用户只需要看到公共接口。

实现步骤

  1. 定义公共接口类:在头文件中定义一个公共接口类,并在其中包含一个指向实现类的私有指针。
  2. 定义实现类:在源文件中定义实现类,包含类的实际实现细节。
  3. 在公共接口类的构造函数和析构函数中管理实现类的指针:在构造函数中创建实现类的实例,在析构函数中销毁它。

典型示例

头文件:Person.h

cpp 复制代码
#ifndef PERSON_H
#define PERSON_H

#include <string>
#include <memory>

class Person {
public:
    Person(const std::string& name, int age);
    ~Person();

    std::string getName() const;
    int getAge() const;
    void setName(const std::string& name);
    void setAge(int age);

private:
    class Impl;  // 前向声明实现类
    std::unique_ptr<Impl> pImpl; // 使用智能指针管理实现类指针
};

#endif // PERSON_H

头文件:PersonImpl.h

cpp 复制代码
#ifndef PERSONIMPL_H
#define PERSONIMPL_H

#include <string>

class Person::Impl {
public:
    Impl(const std::string& name, int age) : name(name), age(age) {}

    std::string name;
    int age;
};

#endif // PERSONIMPL_H

源文件:Person.cpp

cpp 复制代码
#include "Person.h"
#include "PersonImpl.h"

Person::Person(const std::string& name, int age)
    : pImpl(std::make_unique<Impl>(name, age)) {}

Person::~Person() = default;

std::string Person::getName() const {
    return pImpl->name;
}

int Person::getAge() const {
    return pImpl->age;
}

void Person::setName(const std::string& name) {
    pImpl->name = name;
}

void Person::setAge(int age) {
    pImpl->age = age;
}

使用示例:main.cpp

cpp 复制代码
#include <iostream>
#include "Person.h"

int main() {
    Person person("John Doe", 30);
    std::cout << "Name: " << person.getName() << ", Age: " << person.getAge() << std::endl;

    person.setName("Jane Doe");
    person.setAge(25);
    std::cout << "Name: " << person.getName() << ", Age: " << person.getAge() << std::endl;

    return 0;
}

从使用来看,用户仍然是无感的。

通过将 Person 和 PersonImpl 设计成两个不同的头文件,Pimpl Idiom 提供了一种强大的机制来隐藏实现细节,减少编译依赖,并提高代码的封装性和模块化程度。这种设计模式特别适用于需要频繁修改实现但希望接口稳定不变的场景。

Pimpl Idiom 的优点

  1. 隐藏实现细节:用户只能看到头文件中的公共接口,无法看到实现细节。
  2. 减少编译依赖:头文件只包含指向实现类的指针,因此不需要包含实现类的头文件,从而减少编译依赖。
  3. 加快编译时间:由于头文件的变化不会影响依赖该头文件的其他文件,编译时间得到了显著加快。
  4. 二进制兼容性:由于实现类的变化不会影响公共接口类,二进制兼容性得到了保证。

Pimpl Idiom 的缺点

  1. 额外的内存分配和间接访问开销:由于使用了指针,存在额外的内存分配和间接访问的开销。
  2. 代码复杂性增加:需要定义和管理实现类和指针,代码复杂性有所增加。
相关推荐
王小磊学代码28 分钟前
垃圾回收与算法
java·开发语言·jvm
秣宇1 小时前
2024运维人该何去何从?
运维·开发语言·kubernetes·devops
jupiter_8881 小时前
零拷贝技术
java·开发语言
whojoe1 小时前
go switch 与 interface
开发语言·后端·golang
CV-deeplearning1 小时前
如何用python调用C++处理图片
开发语言·c++·python
IT猿手1 小时前
2024最新算法:吸血水蛭优化器(Blood-Sucking Leech Optimizer,BSLO)求解23个函数,MATLAB代码
开发语言·算法·matlab·优化算法·最新算法
微服务技术分享2 小时前
Spring框架的最新进展:2023年Spring Boot和Spring Cloud功能更新
java·开发语言
子蛟2 小时前
关于PHP中删除JSON指定元素unset和array_splice的区别
开发语言·json·php
一百七十五2 小时前
python函数——闭包
开发语言·python
流浪者与猴2 小时前
【C++】函数模板与类模板
开发语言·c++·算法