程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 宏與內聯函數

宏與內聯函數

編輯:C++入門知識

:就是使用一個字符串來代替一個表達式代碼或函數調用代碼;編譯之前,預處理器會使用這個宏字符串所代表的表達式代碼或函數調用代碼來替換所有出現的宏字符串,這樣的話,用宏表示的函數調用代碼就不用另外開辟函數棧,不用保護和恢復函數調用現場,這樣就提高了代碼的執行效率;所以,調用一個宏比調用一個函數更有效;
但是調用宏的時候,有一個缺點:由於宏在預處理時使用的是宏字符串替換,所以,編譯器在編譯的時候不知道宏所代表的代碼的語法,不知道宏所代表的代碼的數據類型,沒有安全檢查;如果出現的類裡面,宏不能訪問類的私有成員,而且容易產生二意性;所以,宏也有自己不能解決的、不可避免的問題;
解決宏定義函數所帶來的問題的辦法,就是使用內聯函數;可以使用內聯函數來代替宏定義;

內聯函數與宏的區別在於:宏是由預處理器來對宏進行替代,沒有語法檢查、類型檢查和安全檢查;內聯函數是通過編譯器的控制來實現的,有語法檢查、類型檢查和安全檢查;內聯函數是真正的函數,而且在調用的地方,由編譯器負責把內聯函數的函數體代碼塊替換到內聯函數被調用的地方,這一點與宏替換很相似;內聯函數有參數,有返回值;由於內聯函數可以像宏一樣被展開,所以調用內聯函數的時候,取消了函數參數壓棧、出棧所帶來的開銷,從而減少了函數調用開銷;這就是內聯函數的優越於宏的地方;

內聯函數的聲明和內聯函數的函數體的定義必須在一起;下面聲明內聯函數的語句是無效的:

inline int Max(int a, int b);

而下面的內聯函數的定義是有效的:

inline int Max(int a, int b){return  ((a > b) ? a : b)};

C++類的成員函數也可以被定義為內聯函數;比如:

class Student
{
  private:
    int nID
    int nAge;
    float fScore;
  public:
    void setID(int nid){ nID = nid; }    //該成員函數默認自動為內聯函數(隱式定義內聯函數)
    int getID(void){ return nID; }       //該成員函數默認自動為內聯函數(隱式定義內聯函數)
    inline void setAge(int nage) { nAge = nage; }   //顯式定義內聯函數
    inline int getAge(void) { return nAge; }        //顯式定義內聯函數
    void setScore(float fscore);         //類定義體內沒有聲明為內聯函數;
    float getScore(void);                //類定義體內沒有聲明為內聯函數;
}
inline void Student::setScore(float fscore){ fScore = fscore; } //類定義體外實現為內聯函數;
inline float Student::getScore(void) { return fScore; }         //類定義體外實現為內聯函數;

 

C++中,在類定義體內部定義了函數體的成員函數,被編譯器默認為內聯函數,而不管這個函數頭前面是否有關鍵字inline,比如:setID()、getID()、setAge()、getAge();也可以把實現在類定義體外部的成員函數定義為內聯函數,這個時候在類定義體中只有成員函數頭的聲明,而其實現是在類定義體外部,比如:setScore()和getScore();

即便是可以把實現在類定義體外部的成員函數定義為內聯函數,那該成員函數的實現也必須寫在聲明類定義體的哪個頭文件(.h)中,不能違反規則;即:內聯函數的定義和實現都必須在同一個頭(.h)文件中;

內聯函數的局限性:

1、由於內聯函數與宏一樣也是實現為代碼替換,所以定義為內聯函數的函數體不宜過大,如果函數體過大,則某些普通的編譯器就會放棄內聯方式,而改用調用普通函數的方式,這樣就失去了內聯函數的意義了;所以,內聯函數的函數體代碼不宜過大,一般就是3---4行代碼即可;

2、由於內聯函數是編譯器在編譯階段進行函數體展開的,所以,這就把類的內聯函數的定義與實現都必須在聲明類的那個頭文件中,而不能放在實現類的那個cpp文件中;這一點與模板template<>的特性相似;

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved