之前在研究AirSim代码时,发现其中MavlinkCom模块,都是写一个MavlinkConnection之类的类,然后再写一个MavlinkConnectionImpl进行实现.一般来说我们都是在设计模式中,发现可以利用接口和实现的分离,来降低程序的耦合度,提高代码的普适性.
不过在C++中,这样做也有另一个方面(编译速度,模块分离)方面的考虑.
下面这段代码,是一段要与COM组建交互的SpeechProvider类,定义大概可以是下面那样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//Header File #pragma once #include <atlbase.h> class SpeechProvider { CComPtr<***> comObj; public: SpeechProvider(); ~SpeechProvider(); int Speak(const char* text); }; //Cpp File #include "SpeechProvider.h" SpeechProvider::SpeechProvider() { //Initialize COM Object } SpeechProvider::~SpeechProvider() { //Uninitialize COM Object } int Speak(const char* text) { //Do Something } |
在SpeechProvider里自然地引入一个相对安全的CComPtr指针,并自然而然地引入atlbase.h到include这个SpeechProvider的所有文件中.
这样将各个地方的头文件全部引入,有时会导致莫名其妙的语法错误(编译器:???是我的锅喽),命名空间混乱,编译速度减慢等等可能的风险.
因为C++在头文件里面只要声明了类型,就能定义那个类型的指针,于是可以以如下的方式,将COM模块头文件限定在SpeechProvider功能的头文件中.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
//Header File #pragma once class SpeechProviderImpl; class SpeechProvider { SpeechProviderImpl* impl; public: SpeechProvider(); ~SpeechProvider(); int Speak(const char* text); }; //Cpp File #include "SpeechProvider.h" #include <atlbase.h> class SpeechProviderImpl { CComPtr<***> comObj; public: SpeechProviderImpl(); ~SpeechProviderImpl(); int Speak(const char* text); }; SpeechProviderImpl::SpeechProviderImpl() { //Initialize COM Object } SpeechProviderImpl::~SpeechProviderImpl() { //Uninitialize COM Object } int SpeechProviderImpl::Speak(const char* text) { //Do Something } SpeechProvider::SpeechProvider() { impl=new SpeechProviderImpl(); } SpeechProvider::~SpeechProvider() { delete impl; } int SpeechProvider::Speak(const char* text) { impl->Speak(text); } |
SpeechProviderImpl实际只有cpp文件中可见,相关的上下文变量也全部存储在Impl类中,从而实现了头文件依赖的分离.避免了各个外部模块中可能发生的冲突问题.
PS:所以说module特性什么时候流行起来呢?
PS2:怀疑肯定在Effective C++之类的书里面看过,只不过自己没注意到
PS3:是的我在弄COM的时候遇到莫名其妙的问题了….x
PS4:依然是f7(eiki)!!!