谈谈 C++ 的私有继承 (Private Inheritance) 在跨平台(Cross Platform)上的妙用

来源:互联网 发布:php ddos攻击 编辑:程序博客网 时间:2024/06/07 22:40

当前mobile平台上主流的C++开发环境有Windows Mobile, Symbian, Brew, Linux等等, 为了加速应用程序在各个平台上的开发, 通常的办法是做一个跨平台的框架(Cross Platform Framework)。那样很多平台无关的代码共享无疑加速了开发,现在关键的问题是如何做到这样平台抽象层。

我们看到过很多和下面类似的代码:

在做完这个东西之后, 我们或者在一个salThread.cpp里面分别用不同的宏SYMBIAN_SAL, WM_SAL来分隔开实现, 或者用3个不同的cpp, 比如salThread_Brew.cpp, salThread_Symbian.cpp。。。那样每个平台找到头文件和对应的cpp也就可以编译了。其实很多的地方都是这样操作的, 包括一些大型的C++跨平台的库也是这样实现着, 但是随着开发的深入, 我们明显感觉到了压力。

第一, 如果程序员不是很熟悉某些特性, 把平台相关的内容遗留在了公共部分!比如一个Brew的程序员不小心在公共的这个头文件里面加入了这个线程的名字

这样他自己的代码通过编译了, 运行okay了, check in了代码, 但是symbian.windows mobile 的代码一看, 编译出错了!!!而且完全不知道怎么办。

第二, 随着平台的增加, 对这个salThread.h的头文件始终处于修改状态, 在#include区域和类成员内部。

这样的话代码慢慢地就会演变成

这不是杞人忧天,危言耸听, 而是真实地反复出现在我们日常的开发中的。这里的平台增加使得这个头文件变成了雷区,在修改的时候稍不注意就会搞得其他平台无法工作,自己调试正确也花了大量的时间!

 

那如何改变这样的状况呢? Private Inheritance这个时候很好的帮助了我们。我们先来看看C++ FAQ里面对此的精彩描述:

private inheritance is a syntactic variant of composition (AKA aggregation and/or has-a).

E.g., the "Car has-a Engine" relationship can be expressed usingsimple composition:

The "Car has-a Engine" relationship can also be expressed usingprivate inheritance:

可以看到这里的私有继承其实提供了一个Has A的关系, 很容易的, 我们可以把他这样用到我们的这个环境里面来! 比如说这样这样, 如此如此:) 我们有一个头文件salThread.h, 这个头文件改成如下的模式:

这里首先一个积极的变换就是, 我们的不同这些宏定义都放在了一个地方。只有一个地方有平台不同的东西, 就是那些#include这里, 除了这个地方, 其他的平台相关性的东西这里都不出现了!再者, 这里的salThread私有继承了salThreadImpl这个类。 很自然的, 我们把这些平台相关性转移到了各个平台相关的头文件里面了, 这个时候, 我的salThread_WM.h就可以类似的写成这个样子:

这个时候, salThread_S60.h, salThread_brew.h也各自有着自己的小天地, 显然就不会再打架了!!包括你要定义一个typedef也不用和别人写在一个地方, 因为这个地方只属于你! 这样平台相关的程序的代码修改就可以尽可能的不影响其他人了。

总结一些来看就是, 我们传统的模式是salThread.h 对应了salThread_wm.cpp, salThread_s60.cpp, salThread_posix.cpp的。这样我们的平台申明的相关性息都在salThread.h里面, 这样我们的修改带来了很多不安全性, 我们现在新的模型就是salThread.h对应salThread_wm.h, salThread_wm.cpp, salThread_s60.h, salThread_s60.cpp. 这样, 我们既通过salThread提供了抽象的接口,同时又有salThread_xx.h帮我们定义了平台特性,不得不说是对前一种实现的进步!

 

原创粉丝点击