c++ 之類的控制與封裝

class和struct的區別

我們可以使用class 和struct 的任何一個來定義類,唯一的一點區別就是struct和class的訪問權限不太一樣。

當我們希望定義的類的所有成員是publ的是,使用struct,反之,如果希望成員是private的,使用class

friend 友元

類可以允許其他類或者函數訪問他的非公有成員,方法是領其他類或者函數稱爲他的友元。

class Sales_data {

//聲明爲友元
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::ostream &print(std::ostream&, const Sales_data&);
friend std::istream &read(std::istream&, Sales_data&);
public:
    // 構造函數
    Sales_data() = default;
    Sales_data(const std::string &s): bookNo(s) { }
    Sales_data(const std::string &s, unsigned n, double p):
               bookNo(s), units_sold(n), revenue(p*n) { }
    Sales_data(std::istream &);

    // 
    std::string isbn() const { return bookNo; }
    Sales_data& combine(const Sales_data&);
    double avg_price() const;
private:
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};


//Sales_data接口的非成員組成部分
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);

友元的聲明只能出現在類定義的內部。友元的聲明僅僅指定了訪問的權限,而非一個普通意義上的函數聲明。如果我們希望類的用戶能夠調用某個友元函數,那麼我們就必須在友元聲明之外再專門對函數進行一次聲明

類之間的友元關係

舉個例子,我們的Window_mgr類的某些成員可能需要訪問它管理的Screen類的內部數據。例如,我們需要爲Window_mgr添加一個名爲clear的成員,它負責吧一個指定的Screen的內容設置爲空白,爲了完成這一任務,clear需要訪問Screen的私有成員,而想要另這種訪問合法,Screen需要把Window_mgr指定爲它的友元。

class Screen{
//Window_mgr 的成員可以訪問Screen類的私有部分
    friend class Window_mgr;
    //Screen類的剩餘部分
}

友元關係不具有傳遞性,也就是說,如果Window_mgr有它自己的友元,則這些友元並不能理所淡然的具有訪問Screen的特權。

令成員函數作爲友元

除了讓整個Window_mgr作爲友元之外,Screen還可以只爲clear提供訪問權限。當把一個成員函數聲明爲友元時,我們必須明確指出該成員函數屬於哪個類。

class Screen{
//Window_mgr::clear 必須在Screen類之前被聲明
    friend void Window_mgr::clear(ScreenIndex);
    //Screen類的剩餘部分
}

友元聲明和作用域

即使我們僅僅是用聲明友元的類的成員調用該函數,它也必須是被聲明過的。

struct X{
friend void f(){//友元函數可以定義在類的內部}
X(){
f();//錯誤,f還沒有被聲明
}
void g();
void h();

};

void X::g(){return f();}//錯誤,f還沒有被聲明

void f();//聲明哪個定義在X中的函數

void X::h(){return f();}//正確:現在f的聲明在作用域中了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章