子类中using引入基类函数时需要注意的情况

    技术2022-05-11  33

    子类中using引入基类函数时需要注意的情况

    class base{public: void test(){  cout << "base::test()" << endl; } void test(int){  cout << "base::test(int)" << endl; }};

    class derived : public base{public: void test(){  cout << "derived::test()" << endl; }};此时derived::test()会隐藏(hide)父类中的两个test重载函数(base::test()和base::test(int)),因此我们为子类中加上一个using声明:class derived : public base{public: void test(){  cout << "derived::test()" << endl; } using base::test;//此声明放在test前面和后面效果都一样};

    现在会不会出现下面所述的情况呢?---------------------------------------------------------------------------------------------------------------既然using base::test将父类中的两个test函数都引入子类,则子类中就相当于有了一个void test()函数,所以我们在子类中重新定义的void test()函数将会和从父类中引入的void test()函数发生冲突,进而出现“重定义”错误。---------------------------------------------------------------------------------------------------------------答案是:不会!此时,子类中重新定义的void test()函数将“顶替”从父类中引入的void test()函数。(PS:从父类中引入的另外一个void test(int)函数则没有发生变化(仍然是父类中的函数实现)。)

     

    类似的另外一种情况如下,此时加入了virtual:class base{public: virtual void test(){  cout << "base::test()" << endl; } virtual void test(double){  cout << "base::test(double)" << endl; } void test(int){  cout << "base::test(int)" << endl; }};

    class derived : public base{public: void test(){  cout << "derived::test()" << endl; }};此时derived::test()虽然重写(override)了base::test(),但是同时也隐藏(hide)父类中的两个test重载函数(一个virtual函数base::test(double)和一个nonvirtual函数base::test(int))。现在,我们为子类中加上一个using声明:class derived : public base{public: void test(){  cout << "derived::test()" << endl; } using base::test;//此声明放在test前面和后面效果都一样};与上面的类似,此时derived::test()“仍然重写”了父类的base::test(),并且与父类中的base::test(double)和base::test(int)[在子类的域]中形成重载集合。

    最后,留一个思考题目,如下:class base{public: virtual void test(){  cout << "base::test()" << endl; } virtual void test(double){  cout << "base::test(double)" << endl; } void test(int){  cout << "base::test(int)" << endl; }};

    class derived : public base{public: void test(){  cout << "derived::test()" << endl; } //using base::test;};

    class A : public derived{public: void test(double){  cout << "A::test(double)" << endl; }};

    int main(int argc, char **argv){ base *pb = new A; pb->test(2.4); return 0;}

    问题:derived中的using base::test加上与否,对程序的结果有什么影响?答:没有影响。(关键点:名字解析是编译时期的事情,而virtual函数动态绑定是运行时期的事情。)(PS:但是将main函数改成“derived *pd = new A; pd->test(2.4);”,则有区别了:如果将using base::test去掉,则编译失败。) 


    最新回复(0)