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

一:成員的訪問權限

1: public訪問權限

    一個類的public成員變量、成員函數,可以通過類的成員函數、類的實例變量進行訪問

   <實際上,類的成員函數,可以訪問本類內的任何成員變量和成員函數>

   

#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繼承


發佈了18 篇原創文章 · 獲贊 25 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章