更新时间:2017-08-22 08:39:14浏览次数:1+次
接上篇。。。
5.基类(父类)指针、继承、virtual关键字实现的多态特性的理解
我们经常会提到面向对象的多态特性。多态特性的实现需要借助成员函数的virtual关键字、继承、基类指针。缺一不可。所以,我们前面在类对象赋值时使用了virtual也是无法实现多态的。因为对象就是对象,对象调用对象的成员函数,始终都是调用对象自己的成员函数,是无法调用赋值的对象的成员函数的。当然,vitrual和继承没有的话,就谈不上多态。而要实现多态,必然要借助基类指针。为什么呢??AA aa;
A *pa = &aa;
pa->show();
//pa->say();//不能访问
BB bb;
pa = &bb;
pa->show();
//pa->say();//不能访问
我们对比前面的代码,发现这里没有A类对象了,而只有A类的指针pa了。pa指针只是指向aa对象或bb对象。然后pa就可以调用两个对象的成员函数了。在A类中,show函数使用了virtual关键字修饰了。AA和BB都继承于A。然后这里用了A类指针。所以他们一起就可以构成多态特性。所以pa由于被不同的对象的地址赋值而产生了不同的输出,这就是多态特性。AA aa;
aa.show();
((A)aa).show();
aa.A::show();
这种情况叫做覆盖。覆盖的原因就是直接当做两个独立的函数在使用。然后使用在函数时,我们无法自动做一个调用的切换。然而多态则不一样。多态的特性就是改变覆盖特性的。通过父类指针指向不同的子类对象时,会将基类被重载的函数穿越到子类对象的函数里执行。也就是说,当加入了virtual关键字的函数,被重载后,编译器会感知到,当调用到了父类的这个重载函数时,就会自动跳到子类的这个重载函数里执行。这个过程是语言标准保证的。AA aa;
AA *pa = &aa;
pa->show();
((A*)pa)->show();
pa->A::show();
总结一下,要实现多态特性,需要父类指针,原因在于父类指针可以调用被指向的子类的继承自父类的函数。需要virtual关键字,,父类指针调用到这个关键字的函数时,就可以去查找子类重载的版本的函数。需要继承,原因在于没有继承,就无法构成父子类的关系,父类指针也就无法指向子类,也就无法触发上面两个过程的执行。另外,子类的继承只是克隆了父类的内容而已,并没有多出来一个父类对象,始终就只有一个子类对象,对象中有多个版本的重载函数定义。所以就会有覆盖和多态调用的现象。相关资讯