c++中的隐藏与java、c#的区别

     上一篇中讲过c++隐藏的情况,可以参考《Effective C++》第50条后部分的内容:

     例如,第一次碰到下面这段代码,大部分人会为它发疯:

class Base { public: virtual void f(int x); }; class Derived: public Base { public: virtual void f(double *pd); }; Derived *pd = new Derived; pd->f(10); // 错误!

      问题在于Derived::f隐藏了Base::f,即使它们取的是不同的参数类型;所以编译器要求对f的调用取一个double*,而10这个数字当然不行。

      这不很合理,但ARM对这种行为提供了解释。假设调用f时,你真的是想调用Derived中的版本,但不小心用错了参数类型。进一步假设Derived是在继承层次结构的下层,你不知道Derived间接继承了某个基类BaseClass,而且BaseClass中声明了一个带int参数的虚函数f。这种情况下,你就会无意中调用了BaseClass::f,一个你甚至不知道它存在的函数!在使用大型类层次结构的情况下,这种错误会时常发生;所以,为了防患于未然,Stroustrup决定让派生类成员按名字隐藏掉基类成员。

 

      Java和c#中在这种情况下不会隐藏基类的方法,基类方法仍然可以调用。C++中隐藏的第一个规则是如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏 。而JAVA中方法名相同但参数不同这种情况就是方法的重载,但是父类的方法还是存在的,你给定父类方法的参数还是可以调用它,但是C++中这种情况父类的方法就被隐藏了。

 

     c++的覆盖在c#中即override。所有的语言在覆盖时,基类函数必须都声明为virtual或abstract类型,若没有这样声明,则子类中出现了与基类中名字相同、参数表相同、返回值相同、抛出异常也相同的函数时会出错。

你可能感兴趣的:(java,C++,C#,Class,语言,编译器)