[Effective C++]條款02:盡量以const,enum,inline 替換#define

來源:互聯網
上載者:User

Prefer consts,enums,and inlines to #defines.

我們學習C語言的時候,經常會用到前置處理器語句,比如#define,#include,#ifdef,#endif.預先處理語句是無法被編譯器看見的,所以無法得到有效錯誤提示.比如說:

   #define ASPECT_RATIO 1.653

記號名稱ASPECT_RATIO有可能沒有進入記號表(symbol table)內.於是當你運用此常量獲得一個編譯錯誤資訊時,錯誤資訊的提示會提到1.653而不是ASPECT_RATIO,如果ASPECT_RATIO被定義在一個非自己寫的標頭檔內,這樣我們就需要花費時間去追蹤錯誤.但想想是不是真的需要花費這樣子的時間來糾正錯誤哪?其實用const替換#define就可以解決這個問題.

   const double AspectRatio=1.653;

因為const會被編譯器看到,當然就會進入記號表內.錯誤提示的時候也就能很快的定位錯誤.

另外使用const還能產生比使用#define更小的碼.因為前置處理器盲目的將所有的ASPECT_RATIO替換為1.653,而改用常量則不會出現這種情況.

 

常量替換#defines的特殊情況:

  (1)定義常量指標

  (2)class專屬常量:範圍和static,範圍確保常量限制於class內.static確保此常量至多隻有一份實體.

 

另外,無法利用#define建立一個class專屬常量.

如果編譯器不允許"static整數型class常量"完成"in class初值設定",可改用所謂的"the enum hack"的補償做法.理論基礎是"一個屬於枚舉型的數值可權充ints被使用",例如:

    class GamePlayer{

         private:

              enum {NumTurns=5};

              int scores[NumTurns];

    }

 

enum hack值得認識的兩個理由:

(1)enum hack的行為某方面說比較像#define而不像const.例如取地址,作用於const常量中是合法的,但作用於enum和#define就是不合法的.

(2)實用主義.

 

#define可以用來實現宏(macros),但宏確實有著很多缺點,比如說:

          #define CALL_WITH_MAX(a,b) f((a)>(b))?(a):(b));

當使用int a=5,b=0; CALL_WITH_MAX(++a,b);調用的使用a被累加了兩次.但宏的優點也是有的,它不會招致函數調用帶來的額外開銷.

為了獲得宏帶來的效率以及一般函數的所有可預料行為和型別安全(type safety)---使用template inline代替它是很好的選擇.

而且如果你要實現一個"class內的private inline函數"#define是做不到的.

 

後話總結:

     對於單純的常量,最好以const或者enums替換#defines

     對於形似函數的宏,最好改用inline函數替換#defines

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.