public继承后,父类与子类访问隐藏

来源:互联网 发布:特朗普访华知乎 编辑:程序博客网 时间:2024/06/11 05:35

转自http://www.cppblog.com/iuranus/archive/2009/01/05/71210.html

 

《Effective C++》的第六章节继承与面向对象设计花了大部分的篇幅在介绍继承遮掩(Hiding Inherited Name),那我也效仿下大师,做个小的总结。
         public继承的目的是要建立父子类的is-a关系,也就是说用到父类的地方,在子类一定能用。现实的代码编写中,我们主要也是用public继承,所以每个人都有自己一套继承的写法和调用,直到看到Effecitve C++时,才会发现还有很多其它的用法,在这里我并不鼓励大家尝试各种写法,毕竟代码要稳定,我只是想把一些可能的形式表现出来,供大家参考。
class Base
{
 public:
       virtual void fn() = 0;
       virtual void fn(int i){printf("/n Base: fn(int)/n");};
       virtual void fn2() {printf("/n Base: void fn2(int)/n");}
       void fn3() {printf("/n Base: fn3()/n");}
       void fn4(){printf("/n Base: fn4()/n");}
};

class ClassA : public Base
{
public:
      ClassA(int n, int d);
      // using Base::fn2;
      virtual void fn(){printf("/n ClassA: fn()/n");};
       virtual void fn(int i){printf("/n ClassA: fn(INT)/n");};

       virtual void fn2(int i) {printf("/n ClassA: fn2(INT)/n"); }

       void fn3() {printf("/n ClassA: fn3()/n");}
       void fn4(int i){printf("/n ClassA: fn4()/n");}
 };

int main()

Base* pBase1 = new ClassA(10, 20);
 pBase1->fn();              //OK,ClassA: fn()
 pBase1->fn(11);          //OK,ClassA: fn(INT)
 pBase1->fn2();            //OK,Base: void fn2(int)
 pBase1->fn2(2);          //NO, 不能访问
 pBase1->fn3();            //OK,Base: fn3()
 pBase1->fn4();            //OK,Base: fn4()
 pBase1->fn4(2);          //NO,不能访问
 printf("/n============================================/n");
 ClassA* pDerived = new ClassA(10, 20);
 pDerived->fn();            //OK,ClassA: fn()
 pDerived->fn(1);          //OK,ClassA: fn(INT)
 pDerived->fn2();          //NO,不能访问
 pDerived->fn2(2);        //OK,ClassA: fn2(INT)
 pDerived->fn3();          //OK,ClassA: fn3()
 pDerived->fn4();          //NO,不能访问
 pDerived->fn4(2);        //NO,ClassA: fn4(INT)
 printf("/n============================================/n");
 return 0;      
}


子类父类同名virtual函数(参数相同), 用子类的指针,引用,对象访问时,子类会覆盖父类方法(只能访问子类方法)。
子类父类同名virtual函数(参数相同), 用父类的指针,引用,对象访问时,子类会覆盖父类方法(只能访问子类方法)。
子类父类同名virtual函数(参数不同), 用子类的指针,引用,对象访问时,子类会覆盖父类方法(只能访问子类方法)。
子类父类同名virtual函数(参数不同), 用父类的指针,引用,对象访问时,父类会覆盖子类方法(只能访问父类方法)。
子类父类同名virtual函数(函数类型不同const/non-const), 用子类的指针,引用,对象访问时,子类会覆盖父类方法(只能访问子类方法)。
子类父类同名virtual函数(函数类型不同const/non-const), 用父类的指针,引用,对象访问时,父类会覆盖子类方法(只能访问父类方法)。

结论:参数和函数类型是c++编译器判断要不要多态的关键因素。注: 返回类型不同时,编译器会报错,virtual不能和static连用。静态成员函数,没有隐藏的this指针,virtual函数一定要通过对象来调用,既要this指针。
改进::如果子类指针想访问到父类,可以在子类里加入:using 父类名::函数名;如pDerived->fn2(); 访问父类方法,在ClassA里面加入using Base::fn2,就可以访问了。如果父类指针想访问到子类,就需要指针转换了。

子类父类同名non-virtual函数(无论参数/返回/函数类型(const或static)),用子类的指针,引用,对象访问,子类会覆盖父类方法(只能访问子类方法)。
子类父类同名non-virtual函数(无论参数/返回/函数类型(const或static)),用父类的指针,引用,对象访问,父类会覆盖子类方法(只能访问父类方法)。

结论: non-virtual函数,既没有任何多态效果,如果父类要访问子类,只用指针转换。

原创粉丝点击