C++对象模型笔记:dynamic binding
编译器对于多态的实现是怎样的呢?下面请看一个例子:
Class Point { Public: Virtual void print(); …… };
Class Point2D : public Point { Public: Virtual void print(); … };
Point2D pt2d; Point *pt = &pt2d; Pt->print(); //这里的多态要求是要调用Point2D:: print( ); { Public: Virtual void print(); …… };
Class Point2D : public Point { Public: Virtual void print(); … };
(实现部分略)
Point2D pt2d; Point *pt = &pt2d; Pt->print(); //这里的多态要求是要调用Point2D:: print( ); |
编译器会怎么做呢?用上一篇笔记里面的name mangling是不行的。
当然,在这个例子里面,如果你编译的时候用优化选项,编译器也许会把上面三条语句优化如下:Point2D pt2d; pt2d.print( ); !!!你也许会惊讶:编译器这么牛?!是的,编译器会分基本快,然后对每一个基本块进行优化合并;(相关知识,请参考编译原理,我也已经忘的差不多了);
但是但对于下面的例子,估计再牛的编译器也没有办法:
view plaincopy to clipboardprint?
//在某处调用: Point2D pt2d;
//在某处调用: Point2D pt2d; |
可以看到,如果不用点措施,牺牲一点东西,printPoint里面是不知道那个Point指针的所指向的真正对象是哪个的。那么,怎么办呢?(换了是你,你说怎么办?)
如果某种技术解决不了某些问题,原因就是在这些问题里面还有一些信息是某些技术所没有用到的。这就是技术的一般方法论(出处在我这里,呵呵)
那么,根据上面的方法论的指导,只需要再增加某些信息,然后再增加某些中间层,把信息放到中间层里面去,也许就可以解决(废话…)
这虽然是废话,但是也显示了多态的实质。所以就叫做显示多态实质的废话吧。
具体如下:
1、编译器遇到了class Point的定义的时候,发现有里面有virtual的成员函数,于是将这个类的定义转换如下:
view plaincopy to clipboardprint? struct Point //虚函数Point::print经过name mangling转化后的全局函数 //编译器自动生成的构造函数经name mangling转换过来的全局函数,以确 void * vtable_Point[] = {&print_Point, } //虚函数表
struct Point //虚函数Point::print经过name mangling转化后的全局函数 //编译器自动生成的构造函数经name mangling转换过来的全局函数,以确 void * vtable_Point[] = {&print_Point, } //虚函数表 |