c++---類的內聯函數,const修飾的函數,友元函數,靜態成員

類的內聯函數,const修飾的函數,友元函數,靜態成員

一.類的內聯函數。

內聯函數從源代碼層看,有函數的結構,而在編譯後,卻不具備函數的性質。內聯函數不是在調用時發生控制轉移,而是在編譯時將函數體嵌入在每一個調用處。編譯時,類似宏替換,使用函數體替換調用處的函數名。一般在代碼中用inline修飾,但是能否形成內聯函數,需要看編譯器對該函數定義的具體處理。

1.在類中被inline修飾的函數就是內聯函數。在編譯時,它將展開在所有調用它的地方。不需要形成函數棧幀,所以節省了成本。就可以提高程序的運行效率。

2.內聯函數是用空間換取時間的一種做法,在調用之處全部展開,使用了空間,但是卻節省了函數壓棧出棧的時間。所以內聯函數只適用於代碼幅度短的函數。若是代碼長度偏長或者代碼短但是有循環或者遞歸的就不適宜作爲內聯函數。

3.inline只是編寫程序者對編譯器的一種建議,有可能編寫者定義了這個函數爲內聯函數,但是編譯器認爲它不可以用作內聯函數,就將這個請求忽略,這樣這個函數還不能作爲內聯函數來使用。

4.inline必須是在函數定義的時候定義,若是定義這個函數時沒有定義爲內聯函數,其餘時間在函數前用inline修飾也是沒有作用的。

5.在c++類中定義的函數默認爲是內聯函數。不需要顯式的用inline修飾,但是一般韓式寫着,比較清楚些,以免有時會有遺忘。

  在寫代碼的時候儘量用const /enum /內聯 /代替宏定義,爲什麼呢?下面我們說一下宏定義的優缺點
宏的優點:

  1. 增強代碼的複用性。
  2. 提高性能

宏的缺點:

  1. 不方便調試宏(因爲在預編譯期間就進行了替換)
  2. 導致代碼的可讀性差,可維護性差,容易誤用。
  3. 沒有類型安全的檢查。
二.類中被const修飾的成員函數。

   之前我接觸過的都是const修飾某個變量,使這個變量不能被改變,具有了常性。在c++中,const還可以被用來修飾函數。就像是下面這個樣子,

class Date
{
public:
//    ①
    void show()
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
//    ②
    void show() const
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
//    ③
    //void show(const Date* this)
    //{
    //    cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    //}
private:
    int _year;
    int _month;
    int _day;
};

在上面這段代碼中,第二個是被const修飾的函數正確寫法。第三個函數是編譯器對第二個函數進行編譯器處理後的結果。這樣來看const還是修飾的變量。它要保證傳進函數的對象不被函數改變。這樣在類中就會有const函數,非const函數,const對象和非const對象,在這些範圍裏,就會產生調用與被調用的關係,那麼在什麼情況下誰可以調用誰,誰不可以調用誰,下面做一個總結。。

  1. const對象可以調用const的函數,const的函數也可以調用const函數
  2. 非const對象可以調用非const函數,非const函數也可以調用非const函數
  3. 非const對象可以調用const函數。非const函數不可以調用const函數
  4. const對象不可以調用非const函數,const函數可以調用非const函數

  處理這類問題只需要記得,const的權限只能縮小不可以擴大。若是const的函數就要保證傳進來的對象不可以被改變,所以它內部不可以調用非const函數。其餘也都是類似的思路。

三.友元函數。

友元函數是可以直接訪問類的私有成員的非成員函數。它是定義在類外的普通函數,它不屬於任何類,但需要在類的定義中加以聲明,聲明時只需在友元的名稱前加上關鍵字friend。

友元函數一般就是在函數聲明前加一個friend修飾,在類內進行聲明,在類外定義。

class Date
{
public:
    friend void show(const Date& d);
    void show()
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
private:
    int _year;
    int _month;
    int _day;
};
void show(const Date& d)
{
        cout<<d._year<<"-"<<d._month<<"-"<<d._day<<endl;
}

上面的用friend修飾的show函數就是友元函數,在類內聲明在類外定義。它可以訪問d的成員變量。即使它不是成員函數。所以,由此看來,友元會破壞類的封裝性。一般情況下不要使用,但是有時候只能使用友元函數才能達到想要的功能,舉個例子,

就像是要重載輸出運算符<<。就必須使用友元函數,爲什麼不可以使用成員函數重載呢?因爲在類中重載的運算符函數的第一個參數都是隱含的this指針所指向的對象,但是輸出運算符的第一個操作數是不是對象。所以就不可以使用成員函數重載。
下面這就是重載的輸出運算符

class Date
{
public:
    friend ostream& operator<<(ostream& os,const Date& d);
private:
    int _year;
    int _month;
    int _day;
};
ostream& operator<<(ostream& out,const Date& d)
{
    out<<"year:"<<d._year<<endl;
    out<<"month:"<<d._month<<endl;
    out<<"day:"<<d._day<<endl;
    return out;
}
四.類的靜態成員。

  在類中被static修飾的成員,就是類的靜態成員。類的靜態成員與類的成員函數比較相似,類的靜態成員是整個類所共享的成員,但是靜態成員沒有this指針,並不是一個對象對應一個靜態成員,而是整個類中的對象的這個靜態成員的值都是一樣的,若被一個改變,則所有對象的這個靜態成員都被改變。
   類中的靜態成員可以是靜態成員函數,也可以是靜態成員變量。若是靜態成員變量,則所有的對象的這個成員變量都一樣。靜態的成員變量只能由靜態的成員函數來調用,因爲靜態的成員變量是共享的,所以它就只對應一個變量,所以,靜態成員函數沒有this指針。這個函數也不可以調用其它的成員函數和成員變量。
  可以直接使用類型作用域訪問符直接調用靜態成員函數。

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