zoukankan      html  css  js  c++  java
  • 訪问控制 protected, public, private 对照

    OOP 3大特性:数据抽象,继承,动态绑定
    3中訪问标号
    protected, public, private 对照

    进行数据抽象;用继承类继承基类的成员,实现继承。通过将基类对应函数声明为virtual,是编译器在执行时决定调用基类函数or派生类函数 完毕动态绑定。即表现多态性
    多态性:利用继承和动态绑定,通过基类指针和引用来表现。

    动态绑定两个条件:1. 虚函数,2. 指针或引用

    class Item_book
    {
        private:
            std::string isdn;
        protected:
            double price;
        public:
            std::string book() const { return isdn; } 
    };

    class Bulk_item::public Item_book
    {
        ...
    };

    void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b)
    {
        cout<<isdn;// error: no access to isdn which is private member in Item_base   (1)
        double ret = price; //ok: use this->price                                     (2)
        ret = d.price;// ok: use price from a Bulk_item object                       (3)
        ret = b.price; // error: no access to price from an Item_base                 (4)
    }

    #include <iostream>
    using namespace std;
     
    class Base
    {   
    private:
        int age;
    protected:
        int num;
    public:
        Base()
        {
            num = 5;
        }
        void set_num( const Base& a)
        {
            cout<<a.num<<endl;
        }
        virtual void show()
        {
            num = 1;
            cout<<num<<endl;
        }
    };
     
    class Devi : public Base
    {
    public:
        void show()
        {
            num = 2;
            cout<<num<<endl;
        }
        void test(const Base &a, const Devi &b)
        {
            cout<<b.num<<endl;  //(5)
        }
    };

    int main()
    {
        Base b, a;
        Devi d;
        b.set_num(a);        (7)
        b.show();
        d.show();  //ok   protected  num可被子类使用
        d.test(b, d); 
        //cout<<d.num; //error  protected  num 不可被子类  对象使用 (6)

        return 0;
    }
    区分(5)(6)的差别,一个在 类的成员函数定义中(能够通过 类对象调用其保护成员。如公有成员一样)。一个在 类定义外部

    总结:
    訪问控制与继承:
    public:
    private: 仅仅能被基类的成员和友元函数訪问。不能被类的对象訪问。同一时候不能被派生类(的成员函数)訪问。例如以下(1)
    protected:能够被派生类(的成员(2))訪问。不能够被派生类对象訪问(6)例外:例外:在派生类内部 能够通过派生类对象訪问其基类的protected)例如以下(3)。同一时候对照下图(5)(6)
    但不能被基类的对象訪问(对于基类,相当于基类的private)例如以下(4)。基类在基类内部能够通过基类对象訪问其protected成员(7)
    即 派生类能够訪问基类 protected 和 public 中的成员。

    公有、私有、保护继承
    对类所继承的成员的訪问由   基类的成员訪问级别和派生类派生列表中使用的訪问标号共同控制
    派生类能够进一步限制,但不能放松对继承的成员訪问。

    派生类中的訪问级别(3种继承方式)
    public:基类成员保持自己的訪问级别:基类的public->派生类的public,基类的protected -> 派生类的protected。 
    protected:基类的public和protected成员在派生类中为proteced成员
    private:基类的全部成员在派生类中为private成员。


    class Base
    {
    public:
        void basemen();
    protected:
        int i;
    private:
        std::string isdn;
        ....
    };
    class Public_derived: public Base
    {
        int use_base() { return i; } //ok: as proteced member in Public_derived
        //...
    };
    class Private_derived: private Base //注意。对照以下
    {
        int use_base()  {return i;} // ok: i is protected member in Base, private member in Pivate_derived
        int print_isdn() {cout<<isdn; } //error: isdn is private member in Base 
    };

    派生訪问标号 还控制来自非直接派生类的訪问:
    class Derived_from_Private: public Private_derived
    {
        //error: Base::i  is private in Private_derived
        int use_base() {return i;}
    };

    class Derived_from_Private: public Public_derived
    {
         //ok: Base::i  remain proteced in Public_derived
        int use_base() {return i;}
    }

    struct VS class
    struct 定义的类 默认范围级别为public类型,定义的派生类 默认具有public继承
    class 定义的类 默认范围级别为private类型,定义的派生类 默认具有private继承

    转换与继承
    能够将派生类转换为基类---通过初始化或复制。 一般调用基类的复制构造函数或赋值函数。
    例:
    Item_base item;                 //object of base type
    Bulk_item bulk;                 //object of derived type
    //ok:use Item_base::Item_base(const Item_base&) constructor
    Item_base item(bulk);           // bulk is "slice down" to its Item_base portion
    //ok:use Item_base::operator = (const Item_base&) 
    item = bulk;                    // bulk is "slice down" to its Item_base portion


    基类  不能自己主动  转换为派生类,否则派生类会訪问 不存在的成员 (基类不存在的成员)。
    除非在 知道 基类向派生类转换为 安全时,能够使用 static_cast强制编译器进行转换。或是
    用 dynamic_cast 申请在执行时进行检測。

    參照 《C++ primer》 第15章

  • 相关阅读:
    格式化日期---获取年月日升级版
    时间格式转换
    Python求两个有序数组的中位数的几种方法
    pyinstaller打包时包含资源文件
    PyQt5自定义组件之飞机水平仪
    Python获取磁盘剩余空间
    PyQt5自定义组件之信号强度
    Python字典的实现原理
    获取元素相对浏览器窗口的偏移坐标
    HTML/JavaScript实现地图以鼠标为圆心缩放和移动
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6809857.html
Copyright © 2011-2022 走看看