1.在声明函数时,在最前加上virtual,则该函数就是函虚数,基类的虚函数被派生类继承后仍是虚函数。
2.派生类中可以重写基类的虚函数。
3.用指针访问重写的虚函数时,被访问的虚函数是指针指向的对象所属类的函数(只看指向的对象所属的类)。
而用指针访问重写的普通函数时,被访问的函数是指针类型所属类的函数(只看指针是什么类)
4.(引用和指针相同)
5. 虚函数的使用:静态关联和动态关联。
有的虚函数在编译时能确定它属于哪个类,这属于静态关联。如:通过对象名调用的虚函数。
有的时候虚函数的应用则可以实现动态关联,如:下面的代码中实现的多态功能,传入不同类的指针,执行不同类中的函数。
#include <iostream> using namespace std; //////////////////////////// class Base { public: void show1(); virtual void show2(); }; void Base::show1() { cout << "Base::show1()...." << endl; } void Base::show2() { cout << "Base::show2()...." << endl; } //////////////////////////// class Child: public Base { public: void show1(); virtual void show2(); //感觉如果show2在其父类已经声明为virtual,这里virtual可以不要。即便接着向下派生,这个virtual写不写都能正确调用下级派生类。 }; //基类的虚函数被派生类继承后仍是虚函数。
void Child::show1() { cout<<"Child::show1()\n"; } void Child::show2() { cout<<"Child::show2()...\n"; } class Child2: public Child { public: void show1(); void show2(); }; void Child2::show1() { cout<<"Child2::show1()\n"; } void Child2::show2() { cout<<"Child2::show2()...\n"; } //////////////////////////// class Test :public Base{ public: virtual void show2(); // 感觉这个virtual可以不要。
}; void Test::show2() { cout<<"Test::show2().."<<endl; } //////////////////////////// void f1(Base *p) { p->show1(); //指针的指向就是Base::show1() //用指针访问重写的普通函数时,被访问的函数是参数列表所声明的类的函数。 } void f2(Base *p) { //用指针访问重写的虚函数时,被访问的虚函数是指针指向的对象所属类的函数。 p->show2(); } void f3(Child *p) { p->show2(); } ////////////////////////////// int main() { Child child; Base base; Test test; Child2 child2 ; //再下级的派生类 f1(&base); //Base::show1()....对于普通函数:被访问的函数是参数列表所声明的类的函数 f1(&child); //Base::show1().... f1(&test); //Base::show1()... f1(&child2); //Base::show1()... f2(&child); //Child::show2()...//用指针访问重写的虚函数时,被访问的虚函数是指针指向的对象所属类的函数 f2(&base); //Base::show2()....//这就是虚函数的意义:函数体一样,却能传入不同的函数指针执行各自的功能 f2(&test); //Test::show2().. f2(&child2); //Child2::show2().. //Child { void show2() ;} 要不要virtual效果一样 f3(&child2); while(1); return 0; }