C++虚函数的陷阱--派生类对象的基类函数调用基类虚函数出错
2015-04-17 10:40
197 查看
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近写程序的时候发现,派生类对象的基类函数如果调用基类虚函数,则它将调用的是派生类的对应函数,而不是我想调用的基类的对应函数。</span>
下面用一个例子来说明:
//基类 class Base { public: void funA(); virtual void funB(); protected: private: }; void Base::funA(){ cout<<"这是Base类funA()"<<endl; funB(); } void Base::funB(){ cout<<"这是Base类funB()"<<endl; } //派生类 class Derivate :public Base { public: virtual void funB(); protected: private: }; void Derivate::funB(){ cout<<"这是Derivate类funB()"<<endl; }我这里创建了一个基类Base和一个派生类Derivate,其中基类有一个函数funA()和一个虚函数funB()。派生类中,我重写函数funB()。
在Base::funA()中我调用了funB(),那么我想要调用的应该是Base::funB()。现在我们试写一下测试:
void main(){ cout<<"1、调用派生类对象的funA():"<<endl; Derivate tmp; tmp.funA(); cout<<"2、调用基类指针指向派生类对象的funA():"<<endl; Base* pBase; pBase = &tmp; pBase->funA(); }
运行结果是:
实际如果我是用派生类对象来调用funA(),那么他将调用Derivate::funB(),而不是Base::funB(),和基类指针指向派生类对象时,运行fun()的结果相同。
解决方法:那么既想要保持funB()函数的多态性,又想在基类能准确调用基类函数Base::funB()应该怎么做呢?那就加上类限定符:
void Base::funA(){ cout<<"这是Base类funA()"<<endl; Base::funB(); }所以,基类函数调用某虚函数时,要注意加上类限定符。
全部测试代码:
#include <iostream>
using namespace std;
//基类 class Base { public: void funA(); virtual void funB(); protected: private: }; void Base::funA(){ cout<<"这是Base类funA()"<<endl; funB(); } void Base::funB(){ cout<<"这是Base类funB()"<<endl; } //派生类 class Derivate :public Base { public: virtual void funB(); protected: private: }; void Derivate::funB(){ cout<<"这是Derivate类funB()"<<endl; }
void main(){ cout<<"1、调用派生类对象的funA():"<<endl; Derivate tmp; tmp.funA(); cout<<"2、调用基类指针指向派生类对象的funA():"<<endl; Base* pBase; pBase = &tmp; pBase->funA(); }
相关文章推荐
- 虚析构函数(删除基类对象时,先调用派生类的虚构函数,再调用基类虚析构函数)
- 使用派生类对象通过成员函数指针调用基类虚函数之不可能性的证明
- 多态继承情况下,有一个基类指针指向派生类对象,如何用它调用基类的虚函数?
- 派生类构造函数中调用基类虚函数,能够发生多态?-(否)
- C++ primer 这本书上有这么两句话“派生类虚函数调用基类版本时,必须显式使用作用域操作符。如果派生类函数忽略了这样做,则函数调用会在运行时确定并且将是一个自身调用,从而导致无穷递归。”
- 虚函数调用时一点注意,调用基类函数时调用派生类函数
- 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针
- C++基类与派生类的函数调用情况
- 关于基类构造函数调用虚函数实际调用的不是派生类的问题的原因
- 解释为什么基类的析构函数不为虚的话,基类指针指向子类对象,删除对象时,派生类的析构函数就不会被调用
- 派生类的对象访问基类中被派生类覆盖或隐藏了的函数或变量
- C++派生类函数调用基类的函数
- C++基类与派生类的函数调用情况
- C/C++中为什么在类外利用多态基类指向派生类指针可以调用类的私有成员函数?
- 页面内调用js函数出错:“缺少对象”的解决方法
- C++如何在派生类成员函数内调用基类的成员函数(包括构造函数)
- C++中通过派生类调用第二基类的普通成员函数时this指针的调整
- C++基类成员函数访问派生类对象的基类成员问题
- 如果基类的析构函数不是virtual的,那么在派生类对象过期时,先调用自己的析构函数,接着会调用基类的析构函数吗?
- 指向子类对象的基类指针调用非虚函数都是基类的函数吗