前记:请搜索PIMPL(private implementantion)模式和桥接模式, PIMPL是桥接模式的一种典型实现

以下转自:http://blog.csdn.net/nrc_douningbo/article/details/5935218

进行跨平台的移植工作,这其中有些地方是无法完全移植过来的,所以:需要我们封装一个接口类,在不同平台下让其有不同的实现。要做到这一点:有很多办法,条件编译啊之类的。但是如果有这种方法,说白了:其还是两份代码,仅仅是放到同一个文件中。参考Qt实现跨平台的办法,正好读了一片这方面的文章,发现PIMPL模式还是很适用的。

  1. ----------------------------------------------------------
  2. //public.h
  3. Class PrivateClass //前置声明
  4. Class PublicA:
  5. {
  6. Public:
  7. PublicA(); //如果私有实现类要调用位于公共类中的方法,则将该公共类指针传给私有类构造函数
  8. ~PublicA();
  9. Private:
  10. PrivateClass* iPoint;  //含有私有实现类的一个指针
  11. Private:
  12. Friend class  PrivateClass; //如果私有实现类要调用公开类的方法,则将之声明为友类。
  13. }
  14. ----------------------------------------------------------
  15. //public.cpp
  16. #include "public.h"
  17. #ifdef Q_OS_SYMBIAN
  18. #include "PrivateClass_symbian.h"
  19. #else
  20. #include "PrivateClass_win32.h"
  21. #endif
  22. PublicA::PublicA()
  23. {
  24. #ifdef Q_OS_SYMBIAN                iPoint = PrivateClass::NewL(this);
  25. #else
  26. iPoint= new PrivateClass(this);
  27. #endif
  28. }
  29. 。。。。。。。
  30. ----------------------------------------------------------

如上:PIMPL是设计了对外公共类和私有实现类。 亦即:多个平台对外的接口都是唯一的这个对外公共类,而不同平台都有自己的私有实现类 。

为了做到这一点,需要如下做:

1:在头文件中:

①声明一下私有类(不是include)

②含有该私有类的一个指针数据成员。

2:在cpp实现文件中:

①用条件编译的方式决定到底include哪个私有实现类的头文件。

②在对外公共类的函数实现中:也用条件编译的方法决定调用哪一个私有实现类的函数。

为了实现这一点,要求:各个私有实现类的类名必须一样!(文件名可以不一致)

以上是一个最简单的模型,当然:如果私有实现类中想调用对外公共类的函数,则需要在公共类中做两件事:

1:在其创建私有类时:通过参数的方式将自己的指针传入到私有类中,从而让私有类含有公共类的指针。

2:在公共类中将私有类声明为:友元类。  (这样扩大了私有类的访问权限,这个可以依据实际情况来确定需要不需要)

事实上:这正是Qt用来对底层操作系统进行抽象的解决办法,它使开发者无需关心每一个平台的底层编程方法和各种限制。

针对qt开发而言:一般这些私有实现类都是针对不同平台的,比如:symbian的一些系同级的函数,还有一些win特有的函数,这些都是无法做到跨平台的,我们可以用PIMPL模式来进行抽象。此时上边所说的条件编译宏就是:不同平台的宏了。同样:还需要在pro中把针对不同平台的私有实现文件放到平台关键字中。

通常,如果公共类名为QMyClass ,那么:

私有类就被定义为QMyClassPrivate。

公共类的源文件和头文件共享公共类名:qmyclass.h,qmyclass.cpp。

私有类的头文件和源文件名以_p 结尾(比如qmyclass_p.h),除非该文件是一个平台特定实现。

平台特定实现的头文件和源文件名中包括平台名 – 如qmyclass_symbian.cpp (不必在结尾处添加_p ,因为已经暗示)。

最新文章

  1. 品味FastDFS~第三回 项目中的FastDFS
  2. jQuery 知识点积累
  3. php--tp中页面之间的跳转
  4. POJ 2516 Minimum Cost 最小费用流
  5. CI 笔记7,easyui 异步加载
  6. 如何查看npm配置?
  7. 7种创建线程方式,你知道几种?线程系列Thread(一)
  8. win10 edge扩展
  9. java里程碑之泛型--使用泛型
  10. Simple 杂题练手记
  11. Property referenced in indexed property path is neither an array nor a List nor a Map
  12. 【漏洞复现】ES File Explorer Open Port Vulnerability - CVE-2019-6447
  13. Celery 出现Process 'Worker-5' pid:5608 exited with 'exitcode 1' 问题
  14. Github上Laravel开源排行榜Star数31-60名
  15. Nginx基本
  16. (xxx.55).toFixed(1) 无法正确进位处理
  17. Java并发编程:阻塞队列 <转>
  18. Linux-文件和目录属性
  19. Redis源代码分析(十二)--- redis-check-dump本地数据库检測
  20. Linux Makefile 教程(转)

热门文章

  1. Android opengl 笔记
  2. JS ES7
  3. linux 下使用 VirtualBox 搭建集群环境
  4. 5.SpringMVC 配置式开发-处理器适配器
  5. 四、DML语言
  6. Hadoop_19_MapReduce&&Yarn运行机制
  7. IDEA intellij 引用jar包方法
  8. Aizu - 1383 Pizza Delivery (最短路图+DAG上的割边)
  9. 【AndroidStudio-添加RecyclerView包】 AndroidStudio添加v7包中的RecyclerView
  10. Clone failed: Could not read from remote repository