Effective C++學習筆記之#define

前言

  條款02:儘可能以const、enum、inline替換#define;儘量用編譯器代替沒必要要的預處理器。函數

 

內容

1、對於單純常量spa

一、const指針

  有兩種特殊的const,常量指針和class專屬常量;code

(1)常量指針

  又分爲常量指針、指針常量、指向常量的指針常量;blog

  • const double *p;或者 double const *p;const讀做常量,*讀做指針,爲常量指針;

  本質是個指針,是指向一個常量的指針,也即指向的內容(*p)不可變。作用域

  • double * const p;*讀做指針,const讀做常量,爲指針常量;

  本質是個常量,是形容這個常量的類型是指針,也即指針指向不能改變。編譯器

  • const double * const p;無論是指針的指向仍是指針的指向內容都是常量,便是指向常量的指針常量。

 

  實際栗子解釋:編譯

const double *p = &b 常量指針;不容許 *p = 6.66,由於常量指針的指向內容是常量不可變;可是容許 p = &c。class

double * const p = &b 指針常量;不容許 p = &c,由於指針常量的指向是常量不可變;可是容許 *p = 6.66。基礎

 

(2)Class的專屬常量

  class專屬常量是指常量的做用域只在class裏,須要在const的基礎上再添加static關鍵字。

    .h頭文件裏聲明 static const double score;

    .cpp實現文件裏設初始值 const double Student::score = 66.6;

(不少編譯器不支持在聲明的時候設置初始值,只能將聲明和設初值分開)

 

二、enum

  若是遇到上述「不支持在聲明的時候設置初始值」,就展示了enum的必要性。

eg:

class A
{
private:
  static const int LEN = 5;
  int score[LEN];
};

  若是編譯器(錯誤地)不容許static整數型class常量完成 in-class 初值設定,就應該用enum來代替:

class A
{
private:
  enum {LEN = 5};
  int score[LEN];
};

 

2、對於形似函數的宏

  將簡單的函數寫成宏,能免去函數調用的一些開銷,可是使用不當會獲得預料以外的結果。

  有個經典的宏問題:

#define FINDMAX(a,b) ( (a) > (b) ? (a) : (b) )
FINDMAX(a++,b); //a被累加兩次
FINDMAX(a++,b+10); //a被累加一次

  用 inline 來代替此類宏的使用,既能免去函數調用的開銷,也能避免一些不可預知的錯誤。

  inline 將函數「內聯」 起來了,在調用的時候是編譯器使用相應的函數代碼替換函數調用。編譯器在調用一個內聯函數時,會首先檢查它的參數的類型,保證調用正確。而後進行一系列的相關檢查,就像對待任何一個真正的函數同樣。這樣就消除了相似#define的隱患和侷限性。

template <typename T>
inline T FindMax(const T& a, const T& b)
{
  return a>b?a:b;
}

 

總結

一、對於單純常量,儘可能用const、enum替換#define;

二、對於形似函數的宏,最好用inline函數代替#define;

相關文章
相關標籤/搜索