在人类最初的时候,你们都是用手吃饭的,可是随着人类的漫长发展,渐渐的开始出现等级制度,部落,再以后,就是国家。每一个国家的人吃饭的方式都不同,英国人用刀叉吃饭,中国人用筷子吃饭。因此,若是想用程序来表现就是,现有一个基类(父类),
ide
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区域实现一个函数,
this
void test_eating(Human& h) { h.eating(); }
接着,我在主函数中,建立三个对象,
spa
Human h; Englishman e; Chinese c;
而后,我去调用这个test_eating()函数,指针
test_eating(h); test_eating(e); test_eating(c);
那么,输出结果会是什么呢?
对象
很明显,这不是咱们想要的结果,咱们明明建立了Englishman对象,Chinese对象,调用test_eating()函数时,却没法输出本身类内部的函数。为了解决这一问题,咱们只要在父类中,对
blog
void eating( void )
这个函数,把它变为虚函数就好了。只要在函数前加上virtual。实现方式以下:继承
virtual void eating( void )
对于这种作同一件事,处理的方式却不一样,这种在C++中被称做是“多态”。也就是说,采用相同的调用方法,对于不一样的对象,会调用不一样的类里面的函数。get
当咱们把eating函数变为虚函数的时候,咱们的目的就达成了。
it
那么多态采用的是什么样的一种机制呢?对于通常的函数,也就是非虚函数,采用的是静态联编,也就是说,非虚函数,在编译时就肯定好了要调用哪一个函数。而对于动态联编,是在运行时才肯定调用的是哪个函数。那么动态联编是如何作到的呢?当一个类内有虚函数时,基于这个类所建立的对象内部都会有一个指针,这个指针指向了虚函数表,当咱们调用函数时,就会根据这个指针找到虚函数表,从而调用虚函数。
那么多态的使用有没有什么特色呢?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; } }
这样作是彻底能够的。