zoukankan      html  css  js  c++  java
  • C++ 派生类成员的访问属性

    派生类成员的访问属性:

    C++继承方式总共分为以下几种:public、private、protected三种(它们直接影响到派生类的成员、及其对象对基类成员访问的规则)。
    (1)public(公有继承):继承时保持基类中各成员属性不变,并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象只能访问基类中的public成员。
    (2)private(私有继承):继承时基类中各成员属性均变为private,并且基类中private成员被隐藏。派生类的成员也只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。
    (3)protected(保护性继承):继承时基类中各成员属性均变为protected,并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。


    由上表可知:

    public继承:不改变基类成员的访问控制。
    private继承:派生类所继承的基类成员的访问控制都变为private。
    protected继承:基类中的private成员的访问控制不变,其余的都变为protected。
    基类的 public成员被派生类继承,且在派生类中是可见的(visible in the derived class)。
    基类的 private成员被派生类继承,但在派生类中是不可见的(not visible in the derived class)。

    受保护成员 protected Members

    以下面两个例子来说明受保护成员的可见性。

    class BC
    {
    public:
        void set_x( int a )
        {
            x = a;
        }
    protected:
        int get_x( ) const
        {
            return x;
        }
    private:
        int x;
    };
    class DC : public  BC
    {
    public:
        void add2()
        {
            int c=get_x();//可以执行
            set_x(c+2);//可以执行
        }
    }
    void  g()
    {
        DC d;
        d.get_x( );//在客户代码中不可见,不能够执行
    }
    class BC
    {
    protected:
        int get_w( ) const;
        //……
    };
    class DC : public BC
    {
    public:
        int get_val( ) const
        {
            return get_w( );//派生类中可见,可以执行
        }
        void base_w( const BC& b ) const
        {
            cout << b.get_w( ) << endl;//客户代码中不可见,不能够执行
        }
    };

    保护成员是专为继承机制而设的。
    受保护成员(A protected member)仅在自己的类和其派生类中是可见的。


    继承方式不会影响基类成员在派生类中的能见度。

    名字隐藏 Name hiding

     如果在派生类中添加了成员(数据、函数),其与基类的成员重名,本地成员(the local member)隐藏继承来的成员 ( hides the inherited member)。

    以下面的代码为例:

    class BC {
      public:
        void h( float );
    };
    
    class DC : public BC {
      public:
        void h( char[ ] );
    };

    DC继承自BC,其中BC含有void h(float)函数,DC中含有void h(char[])函数,这两个函数的签名不同,那么是否能够构成函数的重载呢?

    对于下面的两行代码都能够执行?

    void  f ( )
    { 
        DC d1;
        d1.h( "Boffo!" );//可以执行
        d1.h( 707.7 );//不可以执行
    }

    其实这种想法是不对的,重载必须是同一级的函数才能构成,而这两个函数的级别是不一致的,本地成员void h(char[])将会隐藏继承来的成员 void h(float)!!

    void  f ( )
    { 
        DC d1;
        d1.BC::h( 707.7 );//这样写是可以的
    }

    再就一个例子

    对于一个实现数组升序的类继承自一个数组类。

    class Array
    {
    public:
        void insert(int X)
        {
            将X插入到 last_pos  指定的位置;
            last_pos++;
        }
    private:
        int  last_pos;
        //……
    };
    class AscArray : public Array
    {
    public:
        void insert( int X )
        {
            确定插入的位置,并将X插入
            // ...
        }
        // ...
    };
    

    其调用函数如下调用语法是正确的,但是其内涵错误

    void  f (AscArray& as )
    {
        as.insert( 10 );//正确,排序数组类中插入10然后实现排序
        as.Array::insert(10);//不正确,使用了数组类的插入方法,将10插入到了数组尾部,并不能实现排序功能
    
    }

    调整可访问性 Adjusting access

    一个继承成员的访问控制可能通过使用using声明( using declaration)改变。
    还是上面那个例子。

    class AscArray : public Array 
    {
      private:
        using Array::insert;
        //将基类的public成员的外部访问权降低,使得无法通过派生类对象访问该成员!
      public:
        void insert( int X ) { 
          确定插入的位置,并将X插入
          // ...
        }
      // ...
    };
    void  f(AscArray& as )
    {
        as.insert( 10 );//正确
        as.Array::insert(10);//运行错误
    }

    在使用using声明时,基类中公有的成员在公共派生类中必须是公有的,只有这样才能保证公有继承时“派生类对象是一个基类对象”的逻辑关系。

    在基类中的private成员,不能在派生类中任何地方用using声明。

    同时,在基类中的protected成员,可在public派生下通过using声明改为public成员。

    #include <iostream>
    using namespace std;
    class A
    {
    protected:
        void PrintA( )
        {
            cout << "A::Print"<<endl ;
        }
    };
    class B: public A
    {
    public:
        using A::PrintA;//改为公有
    public:
        void PrintB( )
        {
            cout << "B::Print" <<endl;
        }
    };
    int main( )
    {
        A a;
        B b;
        b.PrintB( );
        b.PrintA( );
        return 0;
    }

  • 相关阅读:
    Day6
    Day6
    Day6
    Day6
    Day6
    Day6
    LeetCode "The Skyline Problem"
    HackerRank
    HackerRank
    HackerRank
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/10737071.html
Copyright © 2011-2022 走看看