條款2:儘量以const,enum,inline替換#define
阿新 • • 發佈:2018-11-26
這一條款也被稱作:寧可用編譯器替換前處理器。對於一般用#defined定義的常量,可以使用const型別代替。但是要注意兩種特殊情況:假如我們要在標頭檔案中定義一個不能被修改的字串,那麼需要使用const char* const型別的指標:
char a = 'A'; char b = 'B'; char* const pa1 = &b;//近水樓臺先得月,const離誰近就修飾誰,const 修飾pa1表明pa1的指向不能變,但是它指的值可以變 //pa1 = &a; 錯誤做法,表明指標的指向不能變 *pa1 = 'C'; //可以改變指標指向物件的值 const char* pa2 = &a; //*pa2 = 'B'; // 指標指向的物件是常量,不能修改 pa2 = &b; //可以改變指標的指向 const char* const cptr = "const";//此時,不論是指標的指向還是指標指向的物件值都不能修改 簡言之,const修飾變數的原則就是:近水樓臺先得月。const離誰近就修飾誰。
第二種情況是與類有關的。你無法通過#define來確定一個有作用域的常數,但是可以用static const來完成。比如你定義了陣列長度為5,可以這樣做。在標頭檔案中:
class Test { private: //記錄整個所有Test型別物件呼叫fun函式的次數 static int times; //陣列的長度 static const int arraySize = 5; public: void fun() { std::cout<<++times<<std::endl; } int Array[arraySize]; };
這裡還有static int times變數的原因是因為它們的宣告、定義完全不同!在對應的原始檔中,只有
#include "item2.h"
int Test::times = 0;
//const int Test::arraySize;
也就是說,對於一般的staic變數(這裡是times),是在標頭檔案中宣告它是static,而在原始檔中定義的;而對於static const變數,假如這個變數是“整數”型別:int,char,bool,那麼直接就可以直接宣告,而不用定義。#define除了定義一些常量之外,使用#define定義巨集,也可以節省函式呼叫的開銷:
#define FIND_MAX_VALUE(a,b) (a) > (b) ? (a) : (b) 然後就可以: int a = 10,b = 5; int c = FIND_MAX_VALUE(a,b);
但是這樣做有一個致命的問題:
int c = FIND_MAX_VALUE(++a,b);後c為12;而int c = FIND_MAX_VALUE(++a,b+10);後c為11!這是一件多麼令人驚奇的事啊!所以,為了防止出現這種亂子,c++提供了行內函數,這種函式在呼叫時,會在呼叫點展開,開銷比較小。
簡而言之:如果是#define常量,用const替換;如果是為了定義類似函式的巨集,則用行內函數替換。
關於我自己
-
一個正派但不正經的程式設計師
-
18年計算機專業碩士畢業生,騰訊SNG部門實習生,現加盟快手科技 ,後端研發工程師一枚
-
喜歡技術,喜歡網際網路
-
民遙控 ,趙雷、陳粒、宋冬野
-
公眾號:程式設計美學,時不時寫篇文章,偶爾數羊,其實說到底,只是想和你聊聊