当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++基础入门教程

C++对象模型笔记:dynamic binding

    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( );
Class Point

{

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?
void printPoint(Point * pt)
{
pt->print();
……
}

 

//在某处调用:
Point pt;

printPoint(&pt);

Point2D pt2d;

//再另外的某处调用
printPoint(&pt);
void printPoint(Point * pt)
{
pt->print();
……
}

 

//在某处调用:
Point pt;

printPoint(&pt);

Point2D pt2d;

//再另外的某处调用
printPoint(&pt);

    可以看到,如果不用点措施,牺牲一点东西,printPoint里面是不知道那个Point指针的所指向的真正对象是哪个的。那么,怎么办呢?(换了是你,你说怎么办?)

    如果某种技术解决不了某些问题,原因就是在这些问题里面还有一些信息是某些技术所没有用到的。这就是技术的一般方法论(出处在我这里,呵呵)

    那么,根据上面的方法论的指导,只需要再增加某些信息,然后再增加某些中间层,把信息放到中间层里面去,也许就可以解决(废话…)

    这虽然是废话,但是也显示了多态的实质。所以就叫做显示多态实质的废话吧。

    具体如下:

    1、编译器遇到了class Point的定义的时候,发现有里面有virtual的成员函数,于是将这个类的定义转换如下:

 view plaincopy to clipboardprint?
//c++ 伪代码,实际的编译器是不会这么做的,他会把这些直接转成机器码。

struct Point
{
void *vptr_point; //vptr,指向下面定义的全局变量vtable_Point;
…. //其他数据成员
};

//虚函数Point::print经过name mangling转化后的全局函数
void print_Point(const Point *p){….}

//编译器自动生成的构造函数经name mangling转换过来的全局函数,以确
//保vptr正确初始化
void Point_constructor(Point *p)
{
p->vptr_point = vtable_Point;
}

void * vtable_Point[] = {&print_Point, } //虚函数表


//c++ 伪代码,实际的编译器是不会这么做的,他会把这些直接转成机器码。

struct Point
{
void *vptr_point; //vptr,指向下面定义的全局变量vtable_Point;
…. //其他数据成员
};

//虚函数Point::print经过name mangling转化后的全局函数
void print_Point(const Point *p){….}

//编译器自动生成的构造函数经name mangling转换过来的全局函数,以确
//保vptr正确初始化
void Point_constructor(Point *p)
{
p->vptr_point = vtable_Point;
}

void * vtable_Point[] = {&print_Point, } //虚函数表

 

共4页 首页 上一页 1 2 3 4 下一页 尾页 跳转到
相关内容
赞助商链接