现在的位置: 首页 > 综合 > 正文

C++继承中覆盖和隐藏基类成员变量或成员函数

2013年10月10日 ⁄ 综合 ⁄ 共 1387字 ⁄ 字号 评论关闭

覆盖
如果派生类覆盖了基类中的成员函数或成员变量,则当派生类的对象调用该函数或
变量时是调用的派生类中的版本,当用基类对象调用该函数或变量时是调用的基类中的版本。

隐藏
看下边这个例子,B继承A   为什么main函数执行fun(x),fun(x,y)时编译通不过
class A
{
    public:
       
    void f(int i,int j){
        i=i+j;
        cout<<i<<endl;
    }
    void f(int i){
        cout<<i<<endl;
    }
};
class B:public A//private A
{
 
    public:
         //using A::fun;
    /*void f(){
        a=10;
        cout<<a<<endl;
    }*/
 private:    
    int a;
};
int main(){
    B m;
    m.f(5,1);
        //m.A::f(5,1);
}

其实很简单
隐藏基类成员函数的情况:如果在派生类中定义了一个与基类同名的函数,不管这个函数的参数列表是不是与基类
中的函数相同,则这个同名的函数就会把基类中的所有这个同名的函数的所有重载版本都隐藏了,这时并不是在派
生类中重载基类的同名成员函数,而是隐藏,比如类A中有函数f(int i,intj)和f(int i)两个版本,当在从A派生出的类
B中定义了基类的f()函数版本时,这时基类中的fun(int  i)和f(int  i,int  j)就被隐藏了,也就是说由类B创建的对象比如
为m,不能直接访问类A中的f(int i)版本,即使用语句m.f(2)时会发生错误。

怎样使用派生类的对象访问基类中被派生类覆盖或隐藏了的函数或变量:

方法 1 使用作用域运算符::,在使用对象调用基类中的函数或变量时使用作用域运算符即语句 m.A::f(2),这
时就能访问基类中的函数或变量版本。注意,访问基类中被派生类覆盖了的成员变量只能用这种方法

方法 2 使用 using:该方法只适用于被隐藏或覆盖的基类函数,在派生类的类定义中使用语句 using 把基类的
名字包含进来,比如using A::f;就是将基类中的函数f()的所有重载版本包含进来,重载版本被包含到子类之
后,这些重载的函数版本就相当于是子类的一部分,这时就可以用派生类的对象直接调用被派生类隐藏了的
基类版本,比如 m.f(2),但是使用这种语句还是没法调用基类在派生类中被覆盖了的基类的函数,比如 m.f()
调用的是派生类中定义的函数f,要调用被覆盖的基类中的版本要使用语句m.A::f()才行。

在派生类的函数中调用基类中的成员变量和函数的方法:就是在函数中使用的被派生类覆盖的基类成员变量或函数
前用作域解析符加上基类的类名,即a::f()就是在派生类的函数中调用基类中被派生类覆盖了的函数f()的方法。

派生类以私有方式被继承时改变基类中的公有成员为公有的方法:
使用::作用域运算符,不提倡用这种方法,在派生类的 public 后面用作用域运算符把基类的 公有成员包函进
来,这样基类的成员就会成为派生类中的公有成员了,注意如果是函数的 话后面不能加括号 ,如A::f;如果
f是函数的话不能有括号
使用using语句,现在一般用这种方法,也是在派生类的public使用using把基类成员包函进来,如using A::f。

抱歉!评论已关闭.