virtual 函数会动态绑定,而virtual函数的缺省参数值是静态绑定的。用一个base类型的指针p去指向一个derived类对象,通过p调用虚函数时,会动态绑定到实际所指对象中的函数;用一个derived类型的指针p2指向一个derived对象,由p2调用函数时,直接就是调用的derived中的函数,其参数值也是derived类中函数对应的参数值。
#include <iostream> using namespace std; class A { public: enum Color {red,green,blue}; A() { cout<<"Construct A"<<endl; } virtual void dodraw() { draw(); } private: virtual void draw(Color color=blue) const { cout<<"base draw:"<<color<<endl; } }; class B:public A { public: B() { cout<<"Construct B"<<endl; } virtual void dodraw() { draw(); } private: virtual void draw(Color color=red) const { cout<<"derived draw:"<<color<<endl; } }; int main() { B b; A *p=&b; B *p2=&b; p->dodraw(); p2->dodraw(); return 0; }
上面的程序中,在B类中都重写了A中的两个virtual函数,从而,通过p和p2调用dodraw函数,其实都是调用的B中dodraw,而B中的dodraw函数调用B中draw函数,从而draw的实参就是B中的缺省实参:red
#include <iostream> using namespace std; class A { public: enum Color {red,green,blue}; A() { cout<<"Construct A"<<endl; } virtual void dodraw() { draw(); } private: virtual void draw(Color color=blue) const { cout<<"base draw:"<<color<<endl; } }; class B:public A { public: B() { cout<<"Construct B"<<endl; } private: virtual void draw(Color color=red) const { cout<<"derived draw:"<<color<<endl; } }; int main() { B b; A *p=&b; B *p2=&b; p->dodraw(); p2->dodraw(); return 0; }
上面的程序,B和A中dodraw函数都是来源于A中,由p和p2调用dodraw时,都是调用的A类中的dodraw函数,dodraw再调用draw函数时,会动态绑定到实际所指的对象B中的draw函数,这在运行期确定,但draw函数的缺省实参是静态绑定的,就是A类中的blue值,这在编译器就已经确定。所以,如果重新定义继承而来的缺省参数值,会出现一种奇怪的现象:virtual函数用的derived类中的,而参数是用的base类中的。
时间: 2024-10-13 01:04:10