通过一个例子讲解下,小弟对虚函数的理解,例子代码如下:
class A{
public:
void print(){ cout<<”This is A”<<endl;}
};
class B:public A{
public:
void print(){ cout<<”This is B”<<endl;}
};
void main()
{
A a;
B b;
a.print();
b.print();
}
这段代码很显然输出的结果是:
This is A
This is B
下面我们把main()函数换下:
void main(){
A a;
B b;
A* p1=&a;
A* p2=&b;
p1->print();
p2->print();
}
那么这段程序的输出结果却是:
This is A
This is A
下面我们在把类A变下,把print()函数声明成虚函数即virtual函数:
class A{
public:
virtual void print(){ cout<<”This is A”<<endl;} //现在成了虚函数了
};
class B:public A{
public:
void print(){ cout<<”This is B”<<endl;} //这里不需要在前面加上关键字virtual
};
在看看这个主函数的输出结果:
void main(){
A a;
B b; // line1
A* p1=&a;
A* p2=&b; // line2
p1->print();
p2->print(); // line3
}
输入的结果为:
This is A
This is B
下面我们分析原因,在这里我们就分析line1,line2,line3就可以了。
在我们未把print()函数声明成虚函数之前,line3产生的结果是:This is A,实际上它是调用了基类的print()函数,而我们在把print()声明成virtual函数后它就调用了类B中的print()函数所以产生的结果是:This is B,其原因如下:
在未把print()函数声明成virtual函数之前,p2是与基类的print()函数进行了绑定,而这种绑定是发生在编译时,具体而言,在编译期绑定时,调用特定函数所必须的代码是由编译器产生的。(编译器绑定也成为静态绑定)
而在print()函数声明成virtual函数之后,p2与print()的绑定就发生在程序的执行期,而不是编译期,这种形式的绑定成为运行期绑定,在运行期绑定中,编译器不生成调用一个特定函数的代码,而是生成足够的信息以使运行期系统能够产生特定的代码以执行相应的函数调用。(运行期绑定也称为动态绑定)
这就是我对其的理解,如有错误之处,请大家多多指教。