C++多态实现及原理1 C++中的多态性是指在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。 多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。多态用虚函数来实现,结合动态绑定。 在C++中,存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。 纯虚函数是虚函数再加上=0;抽象类是指包括至少一个纯虚函数的类。纯虚函数:virtual void fun()=0;即抽象类!必须在子类实现这个函数,即先有名称,没有内容,在派生类实现内容。 例如,在下面的代码中,我们定义了一个基类Father和派生类Son。Father类中有两个函数:Face()和Say(),而Son类继承了Father类,并重写了Say()函数。当我们在main函数中定义了一个Son类的对象son,并将其地址赋给Father类的指针变量pFather,然后调用pFather->Say()时,输出的结果将是"Father say hello"。 这是因为C++编译器在编译的时候,要确定每个对象调用的函数(非虚函数)的地址,这称为早期绑定,当我们将Son类的对象son的地址赋给pFather时,C++编译器进行了类型转换,此时C++编译器认为变量pFather保存的就是Father对象的地址,当在main函数中执行pFather->Say(),调用的当然就是Father对象的Say函数。 从内存角度看,Son类对象的内存模型如上图,我们构造Son类的对象时,首先要调用Father类的构造函数去构造Father类的对象,然后才调用Son类的构造函数完成自身部分的构造,从而拼接出一个完整的Son类对象。当我们将Son类对象转换为Father类型时,该对象就被认为是原对象整个内存模型的上半部分,也就是上图中“Father对象所占内存”,那么当我们利用类型转换后的对象指针去调用它的方法时,当然也就是调用它所在的内存中的方法,因此,输出“Father Say hello”,也就顺理成章了。 要解决这个问题,就要使用晚绑定,当编译器使用晚绑定时候,就会在运行时再去确定对象的类型以及正确的调用函数,而要让编译器采用晚绑定,就要在基类中声明函数时使用virtual关键字,这样的函数我们就称之为虚函数,一旦某个函数在基类中声明为virtual,那么在所有的派生类中该函数都是virtual,而不需要再显式地声明为virtual。 例如,以下代码中,我们将Father类的Say()函数声明为虚函数,那么在Son类中该函数也是虚函数: class Father { public: void Face() { cout << "Father's face" << endl; } virtual void Say() { cout << "Father say hello" << endl; } }; class Son : public Father { public: void Say() { cout << "Son say hello" << endl; } }; void main() { Son son; Father *pFather = &son; pFather->Say(); // 输出"Son say hello" } 在这个例子中,当我们将Son类的对象son的地址赋给Father类的指针变量pFather,然后调用pFather->Say()时,输出的结果将是"Son say hello"。
剩余8页未读,继续阅读
- 粉丝: 23
- 资源: 319
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助