虚函数是定义在基类中的,定义为
virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。定义虚函数的一个重点,我认为这也是虚函数存在的理由:支持动态绑定。
关于动态绑定在C++Primer中的解释是:运行时类型。基类类型的指针和引用可以绑定到派生类型的对象,在这种情况下,静态类型是基类引用(或指针),但动态类型是派生类引用(或指针)。通过基类的引用或指针调用定义为virtual的函数时会发生动态绑定,比如 ,如果调用非虚函数,则无论实际对象是什么类型,都执行基类类型所定义的函数。如果调用虚函数,则直到运行时才能确定调用哪个函数,运行的虚函数是引用所绑定的或指针所指向的对象所属类型定义的版本。
我的朋友lizhaochai给了我几个不错的例子帮我理解,拿出来和大家分享一下。
#include<iostream>
using namespace std;
class s1
{
int i;
public:s1(){}
virtual void print(){cout<<"调用的是基类的print"<<endl;}
void f0(){ cout<<"调用的是基类的f0"<<endl;}
};
class s2:public s1
{
int a;
public: s2(){}
void print(){cout<<"调用的是派生类的print"<<endl;}
void f0(){ cout<<"调用的是子类的f0"<<endl;}
};
int main()
{
s2 x;
s1* p=&x;
p->f0();//大家认为这个输出的是什么呢?
p->print();
system("pause");
return 0;
}
这其中的fO()函数,不是虚函数,所以它不支持动态绑定,所输出的自然是P(基类类型)所定义的函数。当然如果要用基类的指针访问定义于派生类中的成员函数时,必须对指针进行类型转换,将指针显示转换为派生类指针类型,如:((s2*)p)->print();
如果用派生类的指针访问基类的成员函数时,同上。
这只是我的一个小小总结,希望大家多指点。有不好的地方请指出。如果好的话,我可以给分。谢谢。
关于动态绑定在C++Primer中的解释是:运行时类型。基类类型的指针和引用可以绑定到派生类型的对象,在这种情况下,静态类型是基类引用(或指针),但动态类型是派生类引用(或指针)。通过基类的引用或指针调用定义为virtual的函数时会发生动态绑定,比如 ,如果调用非虚函数,则无论实际对象是什么类型,都执行基类类型所定义的函数。如果调用虚函数,则直到运行时才能确定调用哪个函数,运行的虚函数是引用所绑定的或指针所指向的对象所属类型定义的版本。
我的朋友lizhaochai给了我几个不错的例子帮我理解,拿出来和大家分享一下。
#include<iostream>
using namespace std;
class s1
{
int i;
public:s1(){}
virtual void print(){cout<<"调用的是基类的print"<<endl;}
void f0(){ cout<<"调用的是基类的f0"<<endl;}
};
class s2:public s1
{
int a;
public: s2(){}
void print(){cout<<"调用的是派生类的print"<<endl;}
void f0(){ cout<<"调用的是子类的f0"<<endl;}
};
int main()
{
s2 x;
s1* p=&x;
p->f0();//大家认为这个输出的是什么呢?
p->print();
system("pause");
return 0;
}
这其中的fO()函数,不是虚函数,所以它不支持动态绑定,所输出的自然是P(基类类型)所定义的函数。当然如果要用基类的指针访问定义于派生类中的成员函数时,必须对指针进行类型转换,将指针显示转换为派生类指针类型,如:((s2*)p)->print();
如果用派生类的指针访问基类的成员函数时,同上。
这只是我的一个小小总结,希望大家多指点。有不好的地方请指出。如果好的话,我可以给分。谢谢。