在面向对象程序设计中,非常常用的手法就是用基类的指针指向派生类,然后在执行期通过虚函数机制找到派生类中的函数,假设这样一种情况,全局函数有两个输入参数,分别是两个基类指针 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选择正确的函数重载版本。
原文地址:http://blog.csdn.net/zqxnum1/article/details/41722451