C++虚函数的认识

来源:互联网 发布:java ftpclient sftp 编辑:程序博客网 时间:2024/05/29 08:58

关于C++的虚函数,之前有一些疑惑。

就是在子类继承父类后,假如子类和父类有相同原型的函数(如print()),子类在调用该函数时,默认情况下会覆盖父类的该函数。
而在虚函数中讲到,如果使用父类的指针指向子类,同时基类声明虚函数,那么将采用动态联编,即根据当前指针来确定函数。这时如果不采用虚函数,而当前的基类指针指向子类,那么会调用哪个函数呢?答案是调用基类的。

如果你也产生了这个问题,可能就是基础的知识点没有掌握清楚。

所以解决之后总结一下加深印象。

一、首先来看一下普通基类的派生,与下面的含虚函数基类派生对比

基类:

class base{private:int a;public:base(){a = 1;}void print(){cout << "base:"<<a<<endl;}};

派生类:

//派生类1class derived1 :public base{private:int a;public:derived1(){a = 2;}void print(){cout << "derived1:" << a << endl;}};//派生类2class derived2 :public base{private:int a;public:derived2(){a = 3;}void print(){cout << "deroved2" << a << endl;}};
在main函数中

void main(){base* bs = new base();bs->print();bs = new derived1(); bs->print();}
刚开始臆想结果应该是base:1 derived:2;

然而结果是这样的:


也就是说bs两次调用的都是base的print()函数;

二、分析

这里涉及到动态联编和静态联编的问题,简单说一下两者的含义

动态联编:在程序编译阶段不能确定其执行函数,而是在执行阶段根据当前指针来确定执行函数。

静态联编:在程序编译阶段即确定执行函数。

重点总结:虚函数是动态联编的基础。在编译过程中如果检测到基类函数没有使用虚函数,则根据当前指针的类型来确定执行函数体,即在编译过程中已经确定了执行函数体,即使下文指针的指向变量,执行代码仍然不变。

而如果在编译过程中检测到基类使用了虚函数,在把基类和派生类中与虚函数通原型的函数地址列表待查,在执行阶段根据指针当前值来确定执行函数。


所以在没有采用虚函数时,程序不会采用动态联编。也就是说即使程序可以确定当前基类指针时指向派生类,也不会执行派生类函数。

0 0
原创粉丝点击