1. 程式人生 > >C++中關於public、protect、private的訪問許可權控制

C++中關於public、protect、private的訪問許可權控制

一:成員的訪問許可權 1: public訪問許可權     一個類的public成員變數、成員函式,可以通過類的成員函式、類的例項變數進行訪問    <實際上,類的成員函式,可以訪問本類內的任何成員變數和成員函式>     x

#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
    public:
        int pub_mem;
        int pub_fun(){};
    protected:
        int prot_mem;
        int prot_fun(){};
    private:
        int priv_memb;
        int priv_fun(){};
        
};

int main()
{
    AccessTest at;
    at.pub_mem;     //OK, 類變數可以訪問public成員
    at.pub_func();  //OK, 訪問public成員函式是沒有問題的
    
  return 0;
}

2:protected訪問許可權

     一個類的protected成員變數、成員函式,無法通過類的例項變數進行訪問。但是可以通過類的友元函式、友元類進行訪問。

#include<string>
#include<iostream>

using namespace std;

class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}
        
};

class CAtest
{
    public:
        void x()
        {
          AccessTest t;
          t.prot_fun();      //OK,友元類可以訪問protected成員函式
          int x=t.prot_mem;  //OK,友元類可以訪問protected成員變數
       }
};

void Atest()
{
    AccessTest t;
    t.prot_fun();     //OK,友元函式可以訪問protected成員函式
    int x=t.prot_mem;  //OK,友元函式可以訪問protected成員變數
}

int main()
{
    AccessTest at;
    at.prot_mem;      //ERROR,類例項變數無法訪問protected成員變數
    at.prot_fun();    //ERROR,類例項變數無法訪問protected成員函式
    Atest();
    return 0;
}

3:private訪問許可權      一個類的private成員變數、成員函式,無法通過類的例項變數進行訪問。但是可以通過類的友元函式、友元類進行訪問。

#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}
        
};

class CAtest
{
    public:
    void x()
    {
           AccessTest t;
               t.priv_fun();       //OK,友元類可以訪問private成員函式
           int x=t.priv_memb;  //OK,友元類可以訪問private成員變數
        }
};

void Atest()
{
    AccessTest t;
    t.priv_fun();       //OK,友元函式可以訪問private成員函式
    int x=t.priv_memb;  //OK,友元函式可以訪問private成員變數
}

int main()
{
    AccessTest at;
    at.priv_memb;       //ERROR,類例項變數無法訪問private成員變數
    at.priv_fun();      //ERROR,類例項變數無法訪問private成員函式
    Atest();
        return 0;
}

到現在,是否感覺私有訪問屬性,和保護屬性沒有什麼區別?區別主要體現在繼承上面。下面將會講到。

總結:public在任何地方都能訪問,protected只能在派生類中訪問, private只能在友元中訪問。

二:繼承的訪問許可權控制 1:public繼承      派生類通過public繼承,基類的各種許可權不變 。      派生類的成員函式,可以訪問基類的public成員、protected成員,但是無法訪問基類的private成員。      派生類的例項變數,可以訪問基類的public成員,但是無法訪問protected、private成員,彷彿基類的成員之間加到了派生類一般。      可以將public繼承看成派生類將基類的public,protected成員囊括到派生類,但是不包括private成員。

#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}
        
};

class DAccessTest:public AccessTest
{
    public:
        void test()
        {
            int x=pub_mem;     //OK
            pub_fun();         //OK
            
            int y=prot_mem;    //OK
            prot_fun();        //OK
            
            int z=priv_memb;   //ERROR
            priv_fun();        //ERROR
        }
        
};

int main()
{
    DAccessTest dt;
    int x=dt.pub_mem;    //OK
    int y=dt.prot_mem;   //ERROR
    int z=dt.priv_memb;  //ERROR
        return 0;
}

2:protected繼承      派生類通過protected繼承,基類的public成員在派生類中的許可權變成了protected 。protected和private不變。      派生類的成員函式,可以訪問基類的public成員、protected成員,但是無法訪問基類的private成員。      派生類的例項變數,無法訪問基類的任何成員,因為基類的public成員在派生類中變成了protected。      可以將protected繼承看成派生類將基類的public,protected成員囊括到派生類,全部作為派生類的protected成員,但是不包括private成員。      private成員是基類內部的隱私,除了友元,所有人員都不得窺探。派生類的友元,都不能訪問

#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}
        
};

class DAccessTest:protected AccessTest
{
    public:
        void test()
        {
            int x=pub_mem;     //OK
            pub_fun();         //OK
            
            int y=prot_mem;    //OK
            prot_fun();        //OK
            
            int z=priv_memb;   //ERROR
            priv_fun();        //ERROR
        }
        
};

int main()
{
    DAccessTest dt;
    int x=dt.pub_mem;    //ERROR,基類的成員現在是派生類的保護成員
    int y=dt.prot_mem;   //ERROR,基類的成員現在是派生類的保護成員
    int z=dt.priv_memb;  //ERROR
  return 0;
}

3:private繼承      派生類通過private繼承,基類的所有成員在派生類中的許可權變成了private。      派生類的成員函式,可以訪問基類的public成員、protected成員,但是無法訪問基類的private成員。      派生類的例項變數,無法訪問基類的任何成員,因為基類的所有成員在派生類中變成了private。      可以將private繼承看成派生類將基類的public,protected成員囊括到派生類,全部作為派生類的private成員,但是不包括private成員。      private成員是基類內部的隱私,除了友元,所有人員都不得窺探。派生類的友元,都不能訪問

#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}
        
};

class DAccessTest:private AccessTest
{
    public:
        void test()
        {
            int x=pub_mem;     //OK
            pub_fun();         //OK
            
            int y=prot_mem;    //OK
            prot_fun();        //OK
            
            int z=priv_memb;   //ERROR
            priv_fun();        //ERROR
        }
        
};

int main()
{
    DAccessTest dt;
    int x=dt.pub_mem;    //ERROR,基類的成員現在是派生類的私有成員
    int y=dt.prot_mem;   //ERROR,基類的成員現在是派生類的私有成員
    int z=dt.priv_memb;  //ERROR, private成員無法訪問
  return 0;
}

總結:繼承修飾符,就像是一種篩子,將基類的成員篩到派生類。public、protected、private,就是篩子的眼。           通過public繼承,所有基類成員(除了private),public、protected都到了派生類裡面,public篩眼比較大,不會改變訪問許可權。           通過protected繼承,所有基類成員(除了private),public、protected都到了派生類裡面,protected篩眼大小適中,所有過來的成員都變成了protected。           通過private繼承,所有基類成員(除了private),public、protected都到了派生類裡面,private篩眼最小,所有過來的成員都變成了private。     PS:關於class和struct的區別 1:class不寫修飾符,成員預設是private的,而struct 預設是public的

class Base   //預設private
{
    int a;
    int b;
}

Base ba;
int x=ba.a;//錯誤
int y=ba.b;//錯誤

struct St  //預設public
{
    int a;
    int b;
};

St st;
int x=st.a; //OK
int y=st.b;//OK

2:class的繼承預設是private的,而struct預設是public的

class Base{...};
class Derive:Base{...}  //private繼承

struct BStruct{...};
struct DStruct:BStruct{...};//public繼承

原文:https://blog.csdn.net/ycf74514/article/details/49053041