设计模式:多重派遣

来源:互联网 发布:二阶低通滤波算法 编辑:程序博客网 时间:2024/04/28 10:21

在面向对象程序设计中,非常常用的手法就是用基类的指针指向派生类,然后在执行期通过虚函数机制找到派生类中的函数,假设这样一种情况,全局函数有两个输入参数,分别是两个基类指针 A* ap 和 B* bp,那么如何既找到ap指向的准确对象,又找到bp指向的准确对象呢?答案就是多重派遣,既先找到ap(bp)指向的准确对象,再去寻找bp(ap)指向的准确对象,代码示例如下:

#include <iostream>using namespace std;class A {public:virtual void funca() { cout<<"Base A"<<endl; }};class A1 : public A {public:void funca() { cout<<"Derived A1"<<endl; }};class A2 : public A {public:void funca() { cout<<"Derived A2"<<endl; }};class B {public:virtual void funcb(A *p) { cout<<"Base B"<<endl; p->funca();}};class B1 : public B {public: void funcb(A *p) { cout<<"Derived B1"<<endl; p->funca();}};class B2 : public B {public:void funcb(A *p) { cout<<"Derived B2"<<endl; p->funca();}};void func(A *a, B* b) { b->funcb(a); }int main(){B *bp = new B1();A *ap = new A1();func(ap,bp);return 0;}

在上面的例子中,func(A*, B*)就是前面所说的全局函数,最后通过两层虚函数调用将ap和bp指向正确的派生类对象。当然,实现多重派遣不只这一种方法,也可以通过重载的方式来实现,如下:

class B {public:void funcb(A *p) { cout<<"Base B"<<endl; cout<<"Base A"<<endl;;}void funcb(A1 *p) { cout<<"Base B"<<endl; cout<<"Derived A1"<<endl;}void funcb(A2 *p) { cout<<"Base B"<<endl; cout<<"Derived A2"<<endl;}};
在这种情况下,B需要知道A有哪些派生类,然后为A的每一个派生类定义一个函数的重载版本,在A中可以通过将this指针传递给对B的调用,如下:

class A {public:virtual void funca(B *p) { p->funcb(this);}};class A1 : public A {public:void funca(B *p) { p->funcb(this); }};class A2 : public A {public:void funca(B *p) { p->funcb(this);}};
全局函数的定义如下:

void func(A *ap, B* bp) { ap->funca(bp); }
这样首先通过虚函数调用找到了A的派生类对象,然后在A的派生类对象中将this指针传给对B的调用,而此时传进去的this指针已经是派生类的指针,所以可以帮助B选择正确的函数重载版本。





2 0
原创粉丝点击