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

本文涉及的产品
云防火墙,500元 1000GB
简介: 什么是 Private-IMPL ?即【隐藏实现的方式】,如果你还停留在学习的阶段,那这种方式对你的代码几乎毫无用处。但是如果你走入到真实项目当中,这种方式又显得尤为重要。

什么是  Private-IMPL ?

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

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

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

 

为什么:

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

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

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

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

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

 

那什么时候不能使用呢?

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

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

 

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

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

 

演示代码:

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

 

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

#pragma once#include <memory>#include <vector>// 假设这是一个工具类classBrainToolBox{
public:
// 构造和析构函数BrainToolBox();
~BrainToolBox();
// 接口// 比方说...对一个vector进行冒泡排序(无聊)voidSortVector(std::vector<int>&input);
// 比方说...找到一个vector当中的最大值(更无聊)intGetVectorMaxValue(std::vector<int>&input);
// 私有化实现类private:
// 声明实现类classPrivateIMPL;
// 实现类的指针std::unique_ptr<PrivateIMPL>_u;
};

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

 

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

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

#include "BrainToolBoxIMPL.h"// 在构造函数执行时 同时构造实现类BrainToolBox::BrainToolBox(): _u(newBrainToolBox::PrivateIMPL)
{
}
// 毫无存在感的析构 假设不使用智能指针方式 务必在析构中释放实现类的裸指针BrainToolBox::~BrainToolBox()
{
// 假设为裸指针// delete _u;}
// 接口函数 对一个Vector进行冒泡的接口voidBrainToolBox::SortVector(std::vector<int>&input)
{
// 调用实现函数_u->BubbleSortVector(input);
// 假设在实际开发当中 需要将排序结果传出去 这里就可以进行传递操作// zmq_send(socket, vec, len, ZMQ_SNDMORE);return;
}
// 接口函数 找到一个Vector的最大值intBrainToolBox::GetVectorMaxValue(std::vector<int>&input)
{
// 调用实现函数return_u->SearchVectorMaxValue(input);
}

 

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

 

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

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

#pragma once#include "BrainToolBox.h"#include <algorithm>// 定义BrainToolBox的实现类classBrainToolBox::PrivateIMPL{
public:
// 对 Vector 进行冒泡排序的实现函数voidBubbleSortVector(std::vector<int>&vec);
// 找到一个 Vector 当中的最大值实现函数intSearchVectorMaxValue(std::vector<int>&vec);
};

 

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

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

#include "BrainToolBoxIMPL.h"// 实现一个冒泡排序voidBrainToolBox::PrivateIMPL::BubbleSortVector(std::vector<int>&vec)
{
intvec_size=vec.size();
for (size_ti=0; i<vec_size; i++)
    {
inttrend_size=vec_size-i-1;
for (size_tj=0; j<trend_size; j++)
        {
if (vec[j] >vec[j+1])
            {
intk=vec[j];
vec[j] =vec[j+1];
vec[j+1] =k;
            }
        }
    }
return;
}
// 实现返回vector最大值intBrainToolBox::PrivateIMPL::SearchVectorMaxValue(std::vector<int>&vec)
{
automax_item=std::max_element(vec.begin(), vec.end());
return*max_item;
}

 

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

#include <iostream>#include <memory>usingstd::shared_ptr;
#include <vector>usingstd::vector;
#include "BrainToolBox.h"intmain()
{
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>(newBrainToolBox);
std::cout<<"Vector最大值: "<<brain->GetVectorMaxValue(values) <<std::endl;
brain->SortVector(values);
std::cout<<"排序后的Vector:"<<std::endl;
for (auto&item : values)
    {
std::cout<<item<<" ";
    }
returnEXIT_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编译)

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

相关文章
|
1月前
|
自然语言处理 编译器 Linux
|
5月前
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
1月前
|
自然语言处理 编译器 Linux
告别头文件,编译效率提升 42%!C++ Modules 实战解析 | 干货推荐
本文中,阿里云智能集团开发工程师李泽政以 Alinux 为操作环境,讲解模块相比传统头文件有哪些优势,并通过若干个例子,学习如何组织一个 C++ 模块工程并使用模块封装第三方库或是改造现有的项目。
|
2月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
160 21
|
2月前
|
Linux 编译器 C语言
Linux c/c++之多文档编译
这篇文章介绍了在Linux操作系统下使用gcc编译器进行C/C++多文件编译的方法和步骤。
49 0
Linux c/c++之多文档编译
|
2月前
|
算法 编译器 C++
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
96 2
|
3月前
|
数据安全/隐私保护 C语言 C++
C++(七)封装
本文档详细介绍了C++封装的概念及其应用。封装通过权限控制对外提供接口并隐藏内部数据,增强代码的安全性和可维护性。文档首先解释了`class`中的权限修饰符(`public`、`private`、`protected`)的作用,并通过示例展示了如何使用封装实现栈结构。接着介绍了构造器和析构器的使用方法,包括初始化列表的引入以及它们在内存管理和对象生命周期中的重要性。最后,通过分文件编程的方式展示了如何将类定义和实现分离,提高代码的模块化和复用性。
|
5月前
|
C++ 运维
开发与运维编译问题之在C++中在使用std::mutex后能自动释放锁如何解决
开发与运维编译问题之在C++中在使用std::mutex后能自动释放锁如何解决
77 2
|
5月前
|
编译器 C++ 运维
开发与运维编译问题之在C++中创建一个简单的自旋锁如何解决
开发与运维编译问题之在C++中创建一个简单的自旋锁如何解决
32 2
|
5月前
|
C++ 容器
【C++】map和set封装
【C++】map和set封装
44 2