override, overload, hide

    技术2022-05-20  55

    #include <iostream> using std::cout; template<typename T> class complex { T _r, _i; public: complex(T r, T i = 0) :_r(r), _i(i) { } }; class base { public: virtual void f(int){ cout<<"base::f(int)/n"; } virtual void f(double){ cout<<"base::f(double)/n"; } virtual void g(int i = 10){ cout<<"base::g()"<<i <<"/n"; } }; class drived :public base { public: void f(complex<double>){ cout<<"Derived::f(complex)/n"; } void g(int i = 20){ cout<<"derived::g()"<<i<<"/n"; } }; int main() { base b; drived d; base* pb = new drived; b.f(1.0);//1 d.f(1.0);//2 pb->f(1.0);//3 b.g();//4 d.g();//5 pb->g();//6 delete pb; } 

     

    上面这个小程序的输出是神马了??

    要搞清楚上面输出的来龙去脉,首先要弄懂下面的三个概念:

    1. overload。表示在相同的作用域中定义有多个同名的的函数,他们仅在参数列表上不同(参数类型或数量,这里的参数不包括返回值)。在函数调用时由编译器进行重载解析,选择合适的函数进行调用。

    2. override。表示在派生类中定义了一个相同签名的函数(参数个数与类型均与基类的相同)

    3. hide。表示对外层作用域的函数进行隐藏。方法是在内层作用域中定义一个和外层作用域同名的函数。

    第1个,没有问题,输出base::f(double)

    第2个,由于不是使用指针或引用,和重载没关系。有上面的第三点(hide)知,基类中的两个f函数是不可见的,因此这个调用本该失败,但是要注意complex(T r, T i = 0),这可以做为double的一个隐式转换。所以输出是:"Derived::f(complex)

    第3个,pb是基类指针,f是虚函数,但是由函数的参数f不构成override。所以由基类的重载解析知输出为:base::f(double)

    第4个,base::g()10.

    第5个,derived::g()20.

    第6个,呵呵,千万想清楚!这里g构成了override关系,所以调用的应该是drived::g(int),但是这里的默认参数却是来自对象的静态类型(这里是base,参数为10)。所以输出为:derived::g()10

     


    最新回复(0)