1. 程式人生 > >條款2:儘量以const,enum,inline替換#define

條款2:儘量以const,enum,inline替換#define

這一條款也被稱作:寧可用編譯器替換前處理器。對於一般用#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部門實習生,現加盟快手科技 ,後端研發工程師一枚

  • 喜歡技術,喜歡網際網路

  • 民遙控 ,趙雷、陳粒、宋冬野

  • 公眾號:程式設計美學,時不時寫篇文章,偶爾數羊,其實說到底,只是想和你聊聊

  • 在這裡插入圖片描述