前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Example】C++ 用于编译时封装的 Pimpl 演示 (编译防火墙 Private-IMPL)

【Example】C++ 用于编译时封装的 Pimpl 演示 (编译防火墙 Private-IMPL)

原创
作者头像
芯片烤电池
修改于 2022-04-28 02:07:02
修改于 2022-04-28 02:07:02
64900
代码可运行
举报
文章被收录于专栏:C++教程C++教程
运行总次数:0
代码可运行

什么是  Private-IMPL ?

即【隐藏实现的方式】,如果你还停留在学习的阶段,那这种方式对你的代码几乎毫无用处。

但是如果你走入到真实项目当中,这种方式又显得尤为重要。

微软对 Private-IMPL 模式的简单概述(现代C++) 

为什么:

1,它可以对外人尽可能隐藏你类内部实现,因为你的 dll 要给别人用,总要提供头文件,对吧?

2,它可以尽可能减少头文件的 include 次数。

3,它可以尽可能减轻编译依赖,从而提高编译速度。

4,接口与实现分离的概念。

5,提高代码可移植性,接口专注当前项目业务,实现则专注于算法。如果需要复用代码,直接Copy走实现类改名重写接口就可以了。

那什么时候不能使用呢?

1,如果你的类本身非常简单,比如说职责就是共享个数据,就不要使用这种模式,函数的过度嵌套调用会大量消耗栈内存。

2,继承了更深层次的基类,这时你的子类应该专注于业务,将高度复用的代码写入基类,而不是进一步将子类复杂化。

那么  Private-IMPL 的具体实现方式是?

在类内部创建一个私有子类,将函数功能的具体实现写入到私有子类当中,类本身的函数只当做接口专注于业务交互。

演示代码:

================== 创建一个叫大脑工具箱的“工具类” ==================

----------------- 头文件 ----------------- 

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once
#include <memory>
#include <vector>

// 假设这是一个工具类
class BrainToolBox
{
public:
    // 构造和析构函数
    BrainToolBox();
    ~BrainToolBox();

    // 接口

    // 比方说...对一个vector进行冒泡排序(无聊)
    void SortVector(std::vector<int> &input);

    // 比方说...找到一个vector当中的最大值(更无聊)
    int GetVectorMaxValue(std::vector<int>& input);

// 私有化实现类
private:

    // 声明实现类
    class PrivateIMPL;

    // 实现类的指针
    std::unique_ptr<PrivateIMPL> _u;

};

我们已经在类定义头文件中将私有子类声明并且使用智能指针进行包装。

-----------------  CPP 文件 ----------------- 

在构造函数执行时,就要创建子类(实现类)的实例,这时必须要有实现类的定义,接着往下看。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "BrainToolBoxIMPL.h"

// 在构造函数执行时 同时构造实现类
BrainToolBox::BrainToolBox(): _u(new BrainToolBox::PrivateIMPL)
{

}

// 毫无存在感的析构 假设不使用智能指针方式 务必在析构中释放实现类的裸指针
BrainToolBox::~BrainToolBox()
{
    // 假设为裸指针
    // delete _u;
}

// 接口函数 对一个Vector进行冒泡的接口
void BrainToolBox::SortVector(std::vector<int> &input)
{
    // 调用实现函数
    _u->BubbleSortVector(input);

    // 假设在实际开发当中 需要将排序结果传出去 这里就可以进行传递操作
    // zmq_send(socket, vec, len, ZMQ_SNDMORE);
    return;
}

// 接口函数 找到一个Vector的最大值
int BrainToolBox::GetVectorMaxValue(std::vector<int>& input)
{
    // 调用实现函数
    return _u->SearchVectorMaxValue(input);
}

================== 创建大脑工具箱的实现类 ==================

----------------- 头文件 ----------------- 

我们在外部类当中仅仅是将实现类声明,这时就需要进行定义。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once
#include "BrainToolBox.h"

#include <algorithm>

// 定义BrainToolBox的实现类
class BrainToolBox::PrivateIMPL
{
public:
    // 对 Vector 进行冒泡排序的实现函数
    void BubbleSortVector(std::vector<int> &vec);

    // 找到一个 Vector 当中的最大值实现函数
    int SearchVectorMaxValue(std::vector<int>& vec);

};

-----------------  CPP 文件 ----------------- 

将函数的实现代码封装进实现类。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "BrainToolBoxIMPL.h"

// 实现一个冒泡排序
void BrainToolBox::PrivateIMPL::BubbleSortVector(std::vector<int>& vec)
{
    int vec_size = vec.size();
    for (size_t i = 0; i < vec_size; i++)
    {
        int trend_size = vec_size - i - 1;
        for (size_t j = 0; j < trend_size; j++)
        {
            if (vec[j] > vec[j + 1])
            {
                int k = vec[j];
                vec[j] = vec[j + 1];
                vec[j + 1] = k;
            }
        }
    }

    return;
}

// 实现返回vector最大值
int BrainToolBox::PrivateIMPL::SearchVectorMaxValue(std::vector<int>& vec)
{
    auto max_item = std::max_element(vec.begin(), vec.end());
    return *max_item;
}

================== 测试一下 ==================

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>

#include <memory>
using std::shared_ptr;

#include <vector>
using std::vector;

#include "BrainToolBox.h"

int main()
{
    std::cout << "Hello Byte!" << std::endl;
    vector<int> values = {8, 5, 6, 1, 2, 7, 9, 3, 4, 10, 99, 50};
    
    shared_ptr<BrainToolBox> brain = shared_ptr<BrainToolBox>(new BrainToolBox);
    std::cout << "Vector最大值: " << brain->GetVectorMaxValue(values) << std::endl;

    brain->SortVector(values);
    std::cout << "排序后的Vector:" << std::endl;
    for (auto &item : values)
    {
        std::cout << item << " ";
    }

    return EXIT_SUCCESS;
}


====================================

芯片烤电池 C++ Example 2022-Spring Season Pass :

【Example】C++ 标准库常用容器全面概述

【Example】C++ 回调函数及 std::function 与 std::bind

【Example】C++ 运算符重载

【Example】C++ 标准库智能指针 unique_ptr 与 shared_ptr

【Example】C++ 接口(抽象类)概念讲解及例子演示

【Example】C++ 虚基类与虚继承 (菱形继承问题)

【Example】C++ Template (模板)概念讲解及编译避坑

【Example】C++ 标准库 std::thread 与 std::mutex

【Example】C++ 标准库多线程同步及数据共享 (std::future 与 std::promise)

【Example】C++ 标准库 std::condition_variable

【Example】C++ 用于编译时封装的 Pimpl 演示 (编译防火墙 Private-IMPL)

【Example】C++ 单例模式 演示代码 (被动模式、兼容VS2022编译)

====================================

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C++ Primer Plus习题及答案-第十六章
因为string对象提供了自己的内存管理功能,所以不需要再显式定义复制构造函数、析构程序和赋值运算符。
艰默
2023/02/26
9880
C++ Primer Plus习题及答案-第十六章
接口开发,除了Pimpl还应该知道它
在C++开发中,库的接口文件(头文件)的设计至关重要。优秀的设计不仅能够提升封装性,还能减少代码耦合,提高代码的可维护性和可扩展性。在隐藏库的实现细节时,Pimpl(Pointer to Implementation)和虚继承是两种常用的技术。本文将详细对比这两种方法,并结合代码示例,分析其特性及适用场景。
程序员的园
2024/11/22
1130
接口开发,除了Pimpl还应该知道它
C++11智能指针
C成也指针,败也指针。确实,指针给程序员提供了很多便利和灵活性,但是不当的指针使用也会造成很多问题。 Java和C#避免了指针(虽然C#中也能使用指针,但是估计很少有人这样做),其垃圾回收机制,给程序员减轻很多管理内存的负担。
卡尔曼和玻尔兹曼谁曼
2019/01/22
9000
C++11智能指针
C++ 为什么不加入垃圾回收机制
来源:http://www.codeceo.com/article/why-cpp-not-use-gc.html 作者:M-先生 ---- Java的爱好者们经常批评C++中没有提供与Java类似的垃圾回收(Gabage Collector)机制(这很正常,正如C++的爱好者有时也攻击Java没有这个没有那个,或者这个不行那个不够好),导致C++中对动态存储的官吏称为程序员的噩梦,不是吗?你经常听到的是内存遗失(memory leak)和非法指针存取,这一定令你很头疼,而且你又不能抛弃指针带来的灵活性。
范蠡
2022/06/29
9560
C++ 为什么不加入垃圾回收机制
10大性能陷阱!每个C++工程师都要知道
点个关注👆跟腾讯工程师学技术 导语 | 每个C++程序员仿佛都是人形编译器,不止要看懂代码表面的逻辑,甚至要知道每行代码对应的汇编指令。优化代码也成了C++工程师日常必备,正所谓“一杯茶,一包烟,一段代码,优化一天”。在经历过无数个性能优化的日夜后,笔者也总结了几个中过招的性能陷阱,与你分享~ 本文介绍的性能陷阱主要分为两大类:“有成本抽象”和“与编译器作对”。前者是指在使用C++的功能/库时需要注意的隐形成本,后者则是一些C++新手可能会写出不利于编译器优化的代码。另外本文的顺序是由基础到进阶,读者可
腾讯云开发者
2022/11/03
1.2K0
10大性能陷阱!每个C++工程师都要知道
C++避坑指南
导语:如果,将编程语言比作武功秘籍,C++无异于《九阴真经》。《九阴真经》威力强大、博大精深,经中所载内功、轻功、拳、掌、腿、刀法、剑法、杖法、鞭法、指爪、点穴密技、疗伤法门、闭气神功、移魂大法等等,无所不包,C++亦如是。 C++跟《九阴真经》一样,如果使用不当,很容易落得跟周芷若、欧阳锋、梅超风等一样走火入魔。这篇文章总结了在学习C++过程中容易走火入魔的一些知识点。为了避免篇幅浪费,太常见的误区(如指针和数组、重载、覆盖、隐藏等)在本文没有列出,文中的知识点也没有前后依赖关系,各个知识点基本是互
腾讯技术工程官方号
2019/06/12
1.6K0
C++避坑指南
【Example】C++ 接口(抽象类)概念讲解及例子演示
C++ 和 Java 不同的是,C++ 没有 interface 关键字。对于很多新手来说,C++ 当中接口的概念不容易像 Java 当中那样被理解。
芯片烤电池
2022/04/27
2K0
从零开始学C++之boost库(一):详解 boost 库智能指针
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Simba888888/article/details/9569593
s1mba
2019/05/25
6.9K0
整理了70道C语言与C++常见问答题
变量的定义为变量分配地址和存储空间, 变量的声明不分配地址。一个变量可以在多个地方声明, 但是只在一个地方定义。 加入extern 修饰的是变量的声明,说明此变量将在文件以外或在文件后面部分定义。
C语言与CPP编程
2021/02/07
3.2K0
整理了70道C语言与C++常见问答题
【Example】C++ 标准库智能指针 unique_ptr 与 shared_ptr
unique_ptr 类型智能指针在设计上最显著的特点是内部托管的指针一旦被创建就不能被任何形式的复制给另一个unique_ptr,只可以被移动给另一个unique_ptr。unique_ptr 没有拷贝构造函数,因此不能用于赋值。该指针最常用的情况是单例模式和编译防火墙的封装。
芯片烤电池
2022/04/27
1.1K0
【Example】C++ Template (模板)概念讲解及编译避坑
C++ 不同于 Java,它没有标准的 Object 类型。也就意味着 C++ 并不存在完整的泛型编程概念。
芯片烤电池
2022/04/27
8620
C++学习顺序
学习C++的过程可以分为多个阶段,每个阶段都包含了从基础到高级的概念以及相应的代码示例。本文将为你提供一份详细的学习路线,涵盖C++语言的基础语法、面向对象编程、STL(标准模板库)、多线程编程等内容。每个阶段都包含相关的代码样例,帮助你一步步掌握C++。
ljw695
2024/11/21
1570
C++学习顺序
C++11 信号槽 signal/slot
最近在看陈硕大大 的《Linux 多线程服务端编程:使用 muduo C++ 网络库》  ,看到里面用variadic template 和boost智能指针 实现了一个 signal/slot,现在C++11 已经把 boost的智能指针引入到标准库里边了。就想利用纯C++11 实现一遍。
用户7886150
2021/04/26
1.5K0
浅谈C++使用技巧
在软件开发的广阔天地中,C++凭借其强大的性能、灵活性以及对底层硬件的直接控制能力,长期以来一直是系统级编程、游戏开发、高性能计算等领域的重要工具。然而,掌握C++并不只是学习语法那么简单,深入理解其设计理念、最佳实践以及现代化特性,才能真正发挥这门语言的强大潜力。本文旨在深入浅出地介绍C++编程中的十大实用技巧,从内存管理到性能优化,从代码复用到异常处理,旨在帮助开发者编写出既高效又易于维护的C++代码。
Jimaks
2024/06/17
1630
C++ 智能指针详解
http://blog.csdn.net/xt_xiaotian/article/details/5714477
bear_fish
2018/09/20
2K0
Boost C++ 库 | 智能指针(共享指针、共享数组、弱指针、介入式指针、指针容器)入门
Qt历险记
2024/10/10
2400
Boost C++ 库 | 智能指针(共享指针、共享数组、弱指针、介入式指针、指针容器)入门
C++相关基础知识总结笔记
尖括号形式时,预处理器会在标准系统目录中搜索头文件。这种方式主要用于包含标准库提供的头文件,如 <iostream>、<vector> 等。
晨星成焰
2024/09/24
2450
C++相关基础知识总结笔记
每个C++开发者都应该学习和使用的C++11特性
Hi,大家好!本文讨论了所有开发人员都应该学习和使用的一系列 C++11特性。该语言和标准库中有很多新增功能,本文只是触及了皮毛。但是,我相信其中一些新功能应该成为所有C++开发人员的日常工作。
Linux兵工厂
2024/03/21
1180
每个C++开发者都应该学习和使用的C++11特性
你们要的C++面试题答案来了--基础篇
来源:牛客网 地址:http://1t.click/arsc 编辑:公众号【编程珠玑】
编程珠玑
2019/09/23
2.9K0
C++ 新特性学习(一) -- 概述+智能指针(smart_ptr)
C++ 0x/11 终于通过了,真是个很爽的消息。于是乎我决定对新的东西系统学习一下。
owent
2018/08/01
5960
相关推荐
C++ Primer Plus习题及答案-第十六章
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档