文档下载

上一篇文档,PIMPL(一)

1 如何使用PIMPL

  有多种方式实现PIMPL,这里按照《Effective C++》中介绍的方式。

  1.1 基本步骤

  假设原有Person如下:

Person.h

struct Person
{
public:
Person(const int _age);
void print(); private:
int age;
};

Person.cc

Person::Person(const int _age)
: age(_age)
{} void
Person::print()
{
std::cout << "Person::print::age=" << age << std::endl;
}

    1.1.1 将Person改名为PersonImpl

PersonImpl.h

struct PersonImpl
{
public:
PersonImpl(const int _age);
void print(); private:
int age;
};

PersonImpl.cc

PersonImpl::PersonImpl(const int _age)
: age(_age)
{} void
PersonImpl::print()
{
std::cout << "PersonImpl::print::age=" << age << std::endl;
}

    1.1.2 抽象public和protected方法

  将PersonImpl中的public和protected方法成Person。Person中的方法实际调用的是PersonImpl中对应的方法,Person的定义中需要使用PersonImpl,在Person.h文件中绝对不能#include “PersonImpl.h”,这样就是做无用功了。

  • 为什么不能将PersonImpl的对象作为Person的成员变量?

  因为Person类的定义中需要知道该类的大小,如果直接使用PersonImpl的对象,那么就必须知道PersonImpl的定义,而我们恰恰希望在Person的定义中隐藏PersonImpl的定义。这时候,指针就大显神通了。因为指针的大小只与操作系统的位数有关(32位的机器都占4个字节,64位的机器都占8个字节),所以我们可以使用指针指向PersonImpl,从而只需要前置声明就可以了。这就是暗度陈仓吧。

Person.h

struct PersonImpl;  // 前置声明,PIMPL的关键

struct Person
{
public:
Person(const int _age);
void print(); private:
std::shared_ptr<PersonImpl> pImpl; // 指针,暗度陈仓
};

Person.cc

Person::Person(const int _age)
: pImpl(new PersonImpl(_age))
{} void
Person::print()
{
pImpl->print();
}

    1.1.3 使用Person

  在其它地方我们就可以使用Person了,例如:

int main()
{
Person p();
p.print(); return ;
}

    1.1.4     示例源码下载

2 优缺点

  2.1 优点

  • 改变类的私有成员无需重新编译依赖它的文件,所以整个工程重新编译的速度会快很多。
  • 头文件中采用声明式,因此编译时间会快很多。
  • 接口与实现的分离,更有利于单元测试。

  2.2 缺点

  • 实现者需要做更多的工作。
  • 代码会变得不易理解。
  • 运行时动态的获取要执行的方法,性能降低。
  • 需要注意定义拷贝构造换函数或将其禁用。

3 总结

  如《Effective C++》中所说:

  •   如果使用object reference或object pointers可以完成任务,就不要使用objects
  •   尽量以class声明式替换class定义式

4 参考

  1. 《effective C++》 条款31:将文件间的编译关系降至最低
  2. PIMPL Idiom: http://c2.com/cgi/wiki?PimplIdiom

PIMPL(二)的更多相关文章

  1. pImpl

    之前看代码,一直对pIml这个用法一知半解,参考这里 的一篇文章后有所收获. 总结一下,pIml的好处如下: 第一,引入更多的头文件降低编译速度.而且这个声明当然写在一个头文件里,而头文件,是不能预编 ...

  2. 实现私有化(Pimpl) --- QT常见的设计模式

    转载自:http://blog.sina.com.cn/s/blog_667102dd0100wxbi.html 一.遇到的问题 1.隐藏实现 我们在给客户端提供接口的时候只希望能暴露它的接口,而隐藏 ...

  3. 类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等

    一.类声明 //类是一种用户自定义类型,声明形式: class 类名称 {    public:              公有成员(外部接口)    private:              私有 ...

  4. Pimpl Idiom /handle body idiom

    在读<Effective C++>和项目源代码时,看到pImpl Idiom.它可以用来降低文件间的编译依赖关系,通过把一个Class分成两个Class,一个只提供接口,另一个负责实现该接 ...

  5. Qt源码解析之-从PIMPL机制到d指针

    一.PIMPL机制 PIMPL ,即Private Implementation,作用是,实现 私有化,力图使得头文件对改变不透明,以达到解耦的目的 pimpl 用法背后的思想是把客户与所有关于类的私 ...

  6. C++学习笔记之pimpl用法详解

    原文链接:https://www.jb51.net/article/122557.htm 在编写稳定代码是,管理好代码间的依赖性是不可缺少的一个环节.特别是库文件的编写中,减少代码间的依赖性可以提供一 ...

  7. ApacheCN C/C++ 译文集(二) 20211204 更新

    编写高效程序的艺术 零.序言 第一部分:性能基础 一.性能和并发性介绍 二.性能测量 三.CPU 架构.资源和性能 四.内存架构和性能 五.线程.内存和并发 第二部分:高级并发 六.并发和性能 七.并 ...

  8. 【小程序分享篇 二 】web在线踢人小程序,维持用户只能在一个台电脑持登录状态

    最近离职了, 突然记起来还一个小功能没做, 想想也挺简单,留下代码和思路给同事做个参考. 换工作心里挺忐忑, 对未来也充满了憧憬与担忧.(虽然已是老人, 换了N次工作了,但每次心里都和忐忑). 写写代 ...

  9. 前端开发中SEO的十二条总结

    一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...

随机推荐

  1. [Vue warn]: Error in render: "SyntaxError: Unexpected token ' in JSON at position 1"

    一,场景: 字符串转对象: var str = "{'bankRate':5,'YINGUO':0}" 二,操作: JSON.parse(str)时候,报错 [Vue warn]: ...

  2. JUnit(>4.0)@BeforeClass、@Before、@Test、@After、@AfterClass、@Ignore

    JUnit 4 开始使用 Java 5 中的注解(annotation),常用的几个 annotation 介绍: @BeforeClass:针对所有测试,只执行一次,且必须为static void ...

  3. Hibernate 查询sql结果行数的几种方法

    一.前言 这个东西,难度几乎没有,就是繁琐. 一条简单的select count(*) from table_name 都能有多种书写方式. 总是忘,这里记录下. 一 .通过Criteria 查询 C ...

  4. Sublime PlantUML环境配置

    参考[http://www.jianshu.com/p/e92a52770832]在安装中遇到不少问题,总结一次成功的步骤如下 一.安装步骤: 1)准备java  环境 jdk1.7 2)安装Subl ...

  5. VS2003安装Opencv1.0 windows系统 win7

    一.步骤 下载安装opencv1.0     安装文件我上传到百度网盘分享连接 http://pan.baidu.com/s/1o8na0aA 配置电脑windows环境变量 配置VS2003全局设置 ...

  6. Pyqt图标下载网站

    下载地址: https://www.easyicon.net/ 1.程序中图标建议使用32x32的PNG格式. 2.pyinstaller打包中图标建议使用32x32的ICO格式.

  7. Context对象还提供了相应的属性来调整线条及填充风格

    创建一个Canvas画布的方法如下: 复制代码 代码如下: <canvas id=”canvas” width=”600” height=”400”></canvas> 可以在 ...

  8. HDU 5636 Shortest Path(Floyed,枚举)

    Shortest Path Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Tot ...

  9. .Net微服务架构之运行日志分析系统

    一.引言 .Net技术栈目前还没有像spring cloud相对完整一整微服务架构栈,随着业务发展系统架构演进,自行构建.Net技术体系的微服务架构,配套相关核心组件.因平台基于微服务架构方式研发,每 ...

  10. HDU 1711 - Number Sequence - [KMP模板题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Time Limit: 10000/5000 MS (Java/Others) Memory L ...