在人类最初的时候,大家都是用手吃饭的,但是随着人类的漫长发展,渐渐的开始出现等级制度,部落,再之后,就是国家。每个国家的人吃饭的方式都不一样,英国人用刀叉吃饭,中国人用筷子吃饭。所以,如果想用程序来表现就是,现有一个基类(父类),

class Human {public:	void eating( void ) {		cout << "use hand to eat" << endl;	}};

   接着,在父类的基础上,诞生了派生类,英国人,中国人,

class Englishman : public Human {public:	//覆写	void eating(void) {		cout << "use knife to eat" << endl;	}};class Chinese : public Human {public:	void eating(void) {		cout << "use chopstick to eat" << endl;	}};

   子类继承了父类的函数,并对其进行修改,当然只是修改函数的内容,并没有修改函数的返回值类型,函数名,函数参数,这种叫做函数的“覆写”。那么,我现在在global space区域实现一个函数,

void test_eating(Human& h) {	h.eating();}

   接着,我在主函数中,创建三个对象,

        Human h;	Englishman e;	Chinese c;

   然后,我去调用这个test_eating()函数,

        test_eating(h);	test_eating(e);	test_eating(c);

   那么,输出结果会是什么呢?

   很明显,这不是我们想要的结果,我们明明创建了Englishman对象,Chinese对象,调用test_eating()函数时,却无法输出自己类内部的函数。为了解决这一问题,我们只要在父类中,对

void eating( void )

这个函数,把它变为虚函数就行了。只要在函数前加上virtual。实现方式如下:

virtual void eating( void )

对于这种做同一件事,处理的方式却不同,这种在C++中被称作是“多态”。也就是说,采用相同的调用方法,对于不同的对象,会调用不同的类里面的函数。

   当我们把eating函数变为虚函数的时候,我们的目的就达成了。

   那么多态采用的是什么样的一种机制呢?对于一般的函数,也就是非虚函数,采用的是静态联编,也就是说,非虚函数,在编译时就确定好了要调用哪个函数。而对于动态联编,是在运行时才确定调用的是哪一个函数。那么动态联编是如何做到的呢?当一个类内有虚函数时,基于这个类所创建的对象内部都会有一个指针,这个指针指向了虚函数表,当我们调用函数时,就会根据这个指针找到虚函数表,从而调用虚函数。

   那么多态的使用有没有什么特点呢?1.如果调用函数时,传的是值,那么就没有多态,只有传的是指针或引用才会有多态。传值时只能是静态联编。2.只有类的成员函数才能声明为虚函数。3,静态成员函数不能是虚函数。4.内联函数不能是虚函数。5.构造函数不能是虚函数。6.析构函数一般都声明为虚函数。7.重载函数不可设置为虚函数。

   有个很关键的一点就是,如果要把函数设置为虚函数,那么,就得保证函数名相同,函数参数列表相同,函数返回值也应该相同。代码如下:

class Person {public:    virtual void test( void )    {        cout << "Human test() " << endl;     }}class Englishman {public:    virtual void test( void ){                cout << "Englishman test()" << endl;    }}class Chinese {public:    virtual void test( void ){            cout << "Chinese test()" << endl;    }}

   这个时候,设置为虚函数完全是可以的。当然也有例外。就是,可以函数返回值不同。函数的返回值类型跟它的类的类型完全相同,是它的类的指针或引用。代码如下:

class Person {public:    virtual Person* test( void )    {        cout << "Human test() " << endl;        return this;     }}class Englishman {public:    virtual English* test( void ){                cout << "Englishman test()" << endl;        return this;    }}class Chinese {public:    virtual Chinese test( void ){            cout << "Chinese test()" << endl;        return this;    }}

   这样做是完全可以的。