Polymorphism & Virtual Function

Polymorphism & Virtual Function


关于C++多态,看下面的例子:
#include <iostream>
using namespace std;

class Shape
{
public:
	virtual void print(){cout << "Call print()" << endl;}
	virtual void draw(){cout << "Call Shape::draw()" << endl;}
};

class Circle : public Shape
{
public:
	Circle(){cout<< "Call Circle Constructor !" << endl;}
	void draw(){cout << "Call Circle::draw()" << endl;}
	void print(){cout << "Call Circle::print()" << endl;}
};
class Square : public Shape
{
public:
	Square(){cout<< "Call Square Constructor !" << endl;}
	void draw(){cout << "Call Square::draw()" << endl;}
};

class Triangle : public Shape
{
public:
	Triangle(){cout<< "Call Triangle Constructor !" << endl;}
	void draw(){cout << "Call Triangle::draw()" << endl;}
};


int main()
{
	typedef void(*Fun)(void);
	Fun pFun = NULL; 

	Shape *A[]={new Circle,new Square,new Triangle};
	Shape *Temp = new Circle;
	Temp->draw();

	pFun = (Fun)*((int*)*(int*)(Temp)); 
	cout << "(int*)(Temp) " << (int*)(Temp) << endl;
	cout << "*(int*)(Temp) " << *(int*)(Temp) << endl;
	cout << "(int*)*(int*)(Temp) " << (int*)*(int*)(Temp) << endl;
	cout << "(Fun)*((int*)*(int*)(Temp)) " << (Fun)*((int*)*(int*)(Temp)) << endl;
	cout << pFun << endl;
        pFun();

	Circle Cir;
	Cir.draw();
	pFun = (Fun)*((int*)*(int*)(&Cir)); 
	pFun();

	Shape Sh;
	Sh.draw();

	return 0;
}



输出为:
Call Circle Constructor !
Call Square Constructor !
Call Triangle Constructor !
Call Circle Constructor !
Call Circle::draw()
(int*)(Temp) 003965D8
*(int*)(Temp) 4290792
(int*)*(int*)(Temp) 004178E8
(Fun)*((int*)*(int*)(Temp)) 004112D0
004112D0
Call Circle::print()
Call Circle Constructor !
Call Circle::draw()
Call Circle::print()
Call Shape::draw()



调试变量的内容为:
Temp                   0x00393ad0
     [Circle]            {...}
          Shape        {...}
               __vfptr   0x004178e8 const Circle::'vftable'
  [0x0]  0x004112d0 Circle::print(void)
   [0x1]  0x00411005 Circle::draw(void)


Cir                      {...} Circle
      Shape              {...} Shape
__vfptr    0x004178e8 const Circle::`vftable'
[0x0]       0x004112d0 Circle::print(void)
[0x1]       0x00411005 Circle::draw(void)


Sh                       {...} Shape
__vfptr       0x00417bf0 const Shape::`vftable'
[0x0]       0x004112c6 Shape::print(void)
[0x1]       0x00411145 Shape::draw(void)

由调试结果可以看出:
Shape *Temp = new Circle; 和Circle Cir; 即Temp和Cir他们的虚函数列表(vtbl)是一样的,他们的虚函数指针(vptr)同指向一个虚函数列表(0x004178e8 const Circle::`vftable')。

当基类有虚函数时每一个子类都有自己的虚函数列表,而且子类的虚函数列表中的函数会覆盖基类的虚函数。当多态的情况发生时,编辑器会动态的绑定对象所要调用的虚函数,比如: Shape *Temp = new Circle; Temp->draw(); 这个Temp->draw();就是在运行时动态的绑定所要调用的虚函数,根据Circle虚函数列表来确定要调用的函数。










你可能感兴趣的:(C++)