1. 程式人生 > >C++(筆記)淺談protected

C++(筆記)淺談protected

一個類使用protected關鍵字來宣告是希望與派生類分享但是不想被其他公共訪問使用的成員。所以protected可以看做public和private的中間產物

解析protected

1.類似於私有成員,受保護的成員對於類的使用者(類的使用者即類的物件)來說是不可訪問的,也就是說可以通過類的成員函式訪問而不能通過類的物件來訪問
2.類似於公有成員,受保護的成員對於派生類的成員和友元來說是可訪問的,而private基類成員對於派生類成員和友元是不能訪問的
3.派生類的成員或友元只能通過派生類的物件來訪問基類受保護成員,而派生類對基類的物件受保護成員—無許可權

程式碼解析第三點

1.

#include <iostream>
using namespace std;


class Base
{
protected:
    int prot_mem;   
};

class Derive:public Base
{
public:
    friend void Call(Derive &a);//能訪問Derive::prot_mem 
    //friend void Call(Base &b);//不能訪問Base::prot_mem 
private:
    int j;      
};

void
Call(Derive &a) { a.j=a.prot_mem=0; cout<<a.j<<endl; } //void Call(Base &b) //{ // b.prot_mem=0; // cout<<b.prot_mem=0; //} int main() { Derive c; Call(c); //Base d; //Call(d); return 0; } //友元或派生類可以訪問Derive物件的private和protected成員(這裡的成員包括基類中的)

結果
這裡寫圖片描述

2.

若檢查是否能訪問Base物件的protected

#include <iostream>
using namespace std;


class Base
{
protected:
    int prot_mem;   
};

class Derive:public Base
{
public:
    friend void Call(Derive &a);//能訪問Derive::prot_mem 
    friend void Call(Base &b);//不能訪問Base::prot_mem 
private:
    int j;      
};

void Call(Derive &a)
{
    a.j=a.prot_mem=0;
    cout<<a.j<<endl;
}

void Call(Base &b)
{
    b.prot_mem=0;
    cout<<b.prot_mem=0;
}
int main()
{
    Derive c;
    Call(c);
    Base d;
    Call(d);
    return 0;
}

**這段程式碼是不能通過編譯的因為在派生類中的友元函式訪問Base物件的protected了即這裡寫圖片描述

淺談程式碼

重點在於兩個友元(不用也可以)能否訪問Derive物件的private和protected成員和能否訪問Base物件的protected成員

許可權解釋

  • 因為派生類(及其友元)但友元又不是基類的友元,那麼若派生類(及其友元)能改變Base物件的內容,那我們只要定義一個形如Derive的新類就能簡單躲避protected提供的訪問許可權了,但這顯然是不對的,並不是protected的初衷
  • 派生類的成員和友元只能訪問派生類物件中其類受保護成員,對於普通的基類物件中的成員不具備特殊訪問許可權

部分參照c++ primer