您的位置:首页 > 其它

虚函数的总结

2005-04-10 17:30 183 查看
1。虚函数的定义
虚函数是为了更好的实现OO思想的多态性而引入的,即当父类指针指向不同的对象(属于子类或父类)时,调用的将是对象所属类定义的该函数的版本。也就是说同一语句在不同环境下产生不同的效果。
下面是验证代码:
#include <iostream.h>
class myParentsClass
{
public:
myParentsClass()
{
cout<<"myParentsClass::myParentsClass"<<endl;
}

void testFun()
{
cout<<"myParentsClass::testFun"<<endl;
fun();
}
virtual void fun()
{
cout<<"myParentsClass::fun()"<<endl;
}
~myParentsClass()
{
cout<<"myParentsClass::~myParentsClass"<<endl;
}
};

class myClass:public myParentsClass
{
public:
myClass()
{
cout<<"myClass::myClass"<<endl;
}
void fun()
{
cout<<"myClass::fun()"<<endl;
}
~myClass()
{
cout<<"myClass::~myClass"<<endl;
}
};
class mySonClass:public myClass
{
public:
mySonClass()
{
cout<<"mySonClass::mySonClass"<<endl;
}
void fun()
{
cout<<"mySonClass::fun()"<<endl;
}
~mySonClass()
{
cout<<"mySonClass::~mySonClass"<<endl;
}
};

int main()
{
myParentsClass *pClass=NULL;
myClass *pMe=NULL;
myParentsClass myParents;
myClass me;
mySonClass mySon;
// pMe=&myParents; //出错,子类指针不能指向父类对象
pClass=&myParents;
pClass->fun();
pClass=&me;
pClass->fun();
pClass=&mySon;
pClass->fun();
return 0;
}
什么时候适合定义某个函数为虚函数呢?
以上例子得出结论的是 该函数将要在子类中进行改写时
2。虚函数的传递性:
虚函数只向下传递并且不会产生中断,即不会因为子类中没有对虚函数定义而影响该子类的子类同名函数的虚特性。
首先验证 向下传递性质
在主函数中加入如下语句:
........
pMe=&mySon;
pMe->fun(); //具有虚特性,调用的是mySonClass的fun方法
.....
然后验证 不会中断
去掉fun()在myClass的定义.并再次定义一个子类如下:

class myGrandsonClass:pulblic mySonClass
{
public:
void fun()
{
cout<<"myGrandsonClass::fun()"<<endl;
}
};
在主函数中加入如下语句:
.........
mySonClass *pSon=NULL;
myGrandsonClass myGrandson;
pSon=&myGrandson;
pSon->fun(); //可以看到虚函数的特性并没有消失
...........
最后验证虚函数不具备向上传递的特性:
去掉myParentsClass中fun()的修饰符virtual,然后在myClass或者在mySonClass中的fun()前面加上virtual
观察结果。
然后在主函数中加入如下语句:
pMe=&mySon;//只在mySonClass中的fun()的前面加virtual
pMe->fun();
观察结果。
3.虚函数的其他应用
在主函数加入如下代码:
................
pClass=&myParents;
pClass->fun();
pClass->testFun();
pClass=&me;
pClass->fun();
pClass->testFun();
pClass=&mySon;
pClass->fun();
pClass->testFun();
.......................
观察结果可以发现:
testFun()方法也在随指针的指向改变而调用不同的fun()函数。而当去掉fun()前面的virtual时,结果又会不同
由此得出以下结论:
void testFun()
{
cout<<"myParentsClass::testFun"<<endl;
fun(); //这个地方默认是的实际上是this->fun()
//而不是myParentsClass::fun()
}
ps:对于理解 深入浅出MFC第三章会有帮助
又:在主函数中加入如下语句:
myParentsClass *pParents=new myClass();
delete pParents;
pParents=NULL;
观察结果。
可以发现 delete pParents; 并没有调用myParentsClass的析构函数。如果该析构函数负责一些该类动态分配的内存的回收的话,这个语句将会造成严重的后果(指针悬挂).
解决办法:把myParentsClass的析构函数声明为虚函数。
当然如果你并没有打算在子类或子类的子类中重新定义该类(子类....)的析构函数也就不用这末做了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: