利用模板巧妙实现二级接口

来源:互联网 发布:淘宝上签证怎么办理 编辑:程序博客网 时间:2024/05/01 23:41

在面向接口的编程中,如果只有一级接口,那调用和实现都比较简单,但是如果存在二级接口,比如下面的例子:

class IBase{public:virtual void func1(int a) = 0;virtual void func2(int b) = 0;};class ISub1 : public IBase{public:virtual void func3(int c) = 0;virtual void func4(int a) = 0;virtual void func5(int b) = 0;};class ISub2 : public IBase{public:virtual void func6(int a) = 0;virtual void func7(int b) = 0;};
那么该如何实现CSub1,CSub2呢?有人说这样实现:

class CBase:public IBase{};class CSub1:public IBase,ISub1{};

这样的实现是有问题的,编译是无法通过的,因为CSub1继承了两个IBase。

传统的实现模型一般是下列形式:

class CBase{public:virtual void func1(){...}virtual void func2(){...}};class CSub1:public ISub1{public:virtual void func1() {m_pBase->func1();}virtual void func2() {m_pBase->func2();}virtual void func3() {...}virtual void func4() {...}virtual void func5() {...}private: CBase *m_pBase;};class CSub2:public ISub2{public:virtual void func1() {m_pBase->func1();}virtual void func2() {m_pBase->func2();}virtual void func6() {...}virtual void func7() {...}private: CBase *m_pBase;};

从上面的调用可以看出,都需要直接继承ISub1,然后在类中持有一个CBase指针,然后把一些公有方法的实现转交给CBase来实现。如果子类比较多,每一个子类都需要实现一遍公有方法,感觉不够简练。有没有比较好的实现方式呢?


我在开发时,碰到了这个问题,经过研究,发现可以利用模板巧妙实现这种二级接口。

class CBase :public SubInterface{public:CBase() :m_a(0), m_b(0), m_c(0){}virtual void func1(int a){ m_a = a; }virtual void func2(int b){ m_b = b; }public:int m_a;int m_b;int m_c;};template<class SubInterface>class CSub : public CBase<SubInterface>{public:virtual void func4(int d){ m_d = d; }virtual void func5(int e){ m_e = e; }public:int m_d;int m_e;};

实现的关键在CBase类 ,这里的CBase 要继承子接口(是个模板参数),但是又只实现基类功能。一个比较完整的例子如下:

class IA{public:virtual void func1(int a) = 0;virtual void func2(int b) = 0;virtual void func3(int c) = 0;};class IB : public IA{public:virtual void func4(int a) = 0;virtual void func5(int b) = 0;};template<class SubInterface>class CA :public SubInterface{public:CA() :m_a(0), m_b(0), m_c(0){}virtual void func1(int a){ m_a = a; }virtual void func2(int b){ m_b = b; }virtual void func3(int c){ m_c = c; }virtual void funcx(int x){ m_x = x; }public:int m_a;int m_b;int m_c;int m_x;};template<class SubInterface>class CB : public CA<SubInterface>{public:virtual void func4(int d){ m_d = d; }virtual void func5(int e){ m_e = e; }public:int m_d;int m_e;};int _tmain(int argc, _TCHAR* argv[]){cout << "Hello world" << endl;CB<IB> *pxxx = new CB<IB>();IB *pB = (IB *)pxxx;pB->func1(1);pB->func2(2);pB->func3(3);pB->func4(0);pB->func5(-5);getchar();return 0;}


0 0