避免遮掩继承而来的名称 实验示例

来源:互联网 发布:sql 身份证 年龄 编辑:程序博客网 时间:2024/04/28 12:33

只要成员名称一样(即使base classes和derived classes内的函数有不同的参数类型,而且不论函数是vitual或non-virtual),继承类中的名称就会遮掩base class内的名称。

表现如下:

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3. class Base  
  4. {  
  5.       public:  
  6.             void mf1()  
  7.              {cout<<"Base::mf1"<<endl;}  
  8.             void mf1(int a)  
  9.              {cout<<"Base::mf1(int)"<<endl;}  
  10.             void mf2()  
  11.              {cout<<"Base::mf2"<<endl;}   
  12.   
  13. };  
  14. class Derived:public Base  
  15. {  
  16.       public:  
  17.              void mf1()  
  18.              {cout<<"Derived::mf1"<<endl;}  
  19.              void mf2()  
  20.              {cout<<"Derived::mf2"<<endl;}  
  21.              void CallBase()  
  22.              {Base::mf1();}  
  23. };  
  24.   
  25. int main()  
  26. {  
  27.     Derived d;  
  28.     d.mf1();  
  29.     d.CallBase();//正确。如果在类体内通过Base::mf1();则可调用父类的同名函数。  
  30.     d.mf1(1);//报错 no matching function for call to `Derived::mf1(int)'    
  31.              //candidates are: void Derived::mf1()   
  32.     getchar();  
  33. }  
在Base中有mf1(int )函数,但是在Derived类中,已经重载了mf1函数,所以把Base中的所有同名函数都遮掩了。只有mf1()可以通过Derived对象直接调用。

可以Derived类体中直接通过其它函数调用Base中没有被同名遮掩的成员函数,或者通过Derived对象都可以直接调用Base中没有被同名遮掩的成员函数。(前提是满足public\protected\private的继承约束)。例:

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3. class Base  
  4. {  
  5.       public:  
  6.             void init()  
  7.              {cout<<"Base::init"<<endl;}  
  8.             void mf1(int a)  
  9.              {cout<<"Base::mf1(int)"<<endl;}  
  10.             void mf2()  
  11.              {cout<<"Base::mf2"<<endl;}   
  12.   
  13. };  
  14. class Derived:public Base  
  15. {  
  16.       public:  
  17.              void CallBase()  
  18.              {init();}  
  19. };  
  20.   
  21. int main()  
  22. {  
  23.     Derived d;  
  24.     d.CallBase();//正确   
  25.     d.init();//正确   
  26.     getchar();  
  27. }  
输出:


一个virtual函数的例子:

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3. class Base  
  4. {  
  5.       public:  
  6.             void init()  
  7.              {mf1();}  
  8.       private:  
  9.            virtual void mf1()  
  10.              {cout<<"Base::mf1"<<endl;}  
  11. };  
  12. class Derived:public Base  
  13. {  
  14.       private:  
  15.               virtual void mf1()  
  16.               {cout<<"Derived::mf1"<<endl;}  
  17. };  
  18.   
  19. int main()  
  20. {  
  21.     Derived d;  
  22.     d.init();//正确  
  23.     Base b;  
  24.     b.init();  
  25.     Base &tb=d;  
  26.     tb.init();   
  27.     getchar();  
  28. }  

通过基类的init()访问不同类型的mf1(),实现多态。

如果private继承则:

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3. class Base  
  4. {  
  5.       public:  
  6.             void init()  
  7.              {mf1();}  
  8.       private:  
  9.            virtual void mf1()  
  10.              {cout<<"Base::mf1"<<endl;}  
  11. };  
  12. class Derived:private Base  
  13. {  
  14.       private:  
  15.               virtual void mf1()  
  16.               {cout<<"Derived::mf1"<<endl;}  
  17. };  
  18.   
  19. int main()  
  20. {  
  21.       Derived d;  
  22.   //  d.init();//报错:`void Base::init()' is inaccessible    
  23.              //`Base' is not an accessible base of `Derived'   
  24.     Base b;//正确   
  25.     b.init();//正确   
  26.  //   Base &tb=d;//报错 `Base' is not an accessible base of `Derived'   
  27.   //  tb.init();   
  28.     
  29.     getchar();  
  30. }  


上面代码再变化,把d存到Base b中,造成切割后:

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3. class Base  
  4. {  
  5.       public:  
  6.             void init()  
  7.              {mf1();}  
  8.       private:  
  9.            virtual void mf1()  
  10.              {cout<<"Base::mf1"<<endl;}  
  11. };  
  12. class Derived:public Base  
  13. {  
  14.       private:  
  15.               virtual void mf1()  
  16.               {cout<<"Derived::mf1"<<endl;}  
  17. };  
  18.   
  19. int main()  
  20. {  
  21.     Derived d;  
  22.     Base b=d;//Derived部分被切割掉了,结果只剩下基类的mf1可供选择了。   
  23.     b.init();  
  24.     getchar();  
  25. }  
结果:



通过using声明式让被遮掩的成员函数重见天日:

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3. class Base  
  4. {  
  5.       public:  
  6.            void mf1()  
  7.            {cout<<"Base::mf1"<<endl;}  
  8.            void mf1(int x)  
  9.            {cout<<"Base::mf1(int)"<<endl;}  
  10. };  
  11. class Derived:public Base  
  12. {  
  13.       public:  
  14.              using Base::mf1;//这里用了using 声明式   
  15.               void mf1()  
  16.               {cout<<"Derived::mf1"<<endl;}  
  17. };  
  18.   
  19. int main()  
  20. {  
  21.     Derived d;  
  22.     d.mf1();  
  23.     d.mf1(1);//有了using Base::mf1 就Derived对象就可以访问基类中被遮掩的同名函数了   
  24.     getchar();  
  25. }  

通过using声明式,在Derived类中引入基类被隐藏的函数。

通过转交函数让基类中的函数重见天日:

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3. class Base  
  4. {  
  5.       public:  
  6.            void mf1()  
  7.            {cout<<"Base::mf1"<<endl;}  
  8.            void mf1(int x)  
  9.            {cout<<"Base::mf1(int)"<<endl;}  
  10. };  
  11. class Derived:public Base  
  12. {  
  13.       public:  
  14.               void mf1()  
  15.               {Base::mf1();} //转交   
  16. };  
  17.   
  18. int main()  
  19. {  
  20.     Derived d;  
  21.     d.mf1();   
  22.     getchar();  
  23. }  
结果:

原创粉丝点击