盡量以const、enum和inline代替#define
一、#define的功能
參考:(1) #define的變體,即#ifndef,可以防止頭頭檔案的重複引用
#ifdef和 #define組合,一般用於標頭檔案中,用以實現防止多個檔案對此同乙個標頭檔案的重複引用.實際使用中,即使你的標頭檔案暫時沒有被多個檔案所引用,為了增加程式可讀性,移植性,健壯性等,還是最好都加上。其用法一般為:
#ifndef 標識》
#define 標識》
……… // include or define sth.
#endif
(2) #define的變體,即#ifdef,可以實現加入自己需要的模組(原始檔)
在原始檔中加入
#ifdef myself_h
#include "myself.c"
#endif
可以實現在原始檔中加入myself.c的**,將其實現的功能加進來, 即加入了myself模組
(3) #define可以進行巨集定義常量
#define pi 3.1415926
#define radius 5
而在表達該圓的面積的時候,就可以用下面的表示了:
#define area ((pi)*( radius)*( radius))
巨集定義有一些缺點:
(1) 無法對巨集定義中的變數進行型別檢查
(2) 邊界效應
二、const、enum與#define
define定義的變數,是compile-time時期的變數,系統在編譯時候,就將其全部替換,而不會對其變數進行型別等屬性檢查,相對不是很安全,可能存在潛在的問題,而沒有發現.
正因為其僅僅是編譯時期替換,所以其定義的變數,是不會在執行時候分配記憶體的,不占用記憶體空間.
const定義的變數,是 run-time時期的變數,如果型別不匹配,系統在執行時候,就會發現並提示或報錯,對應的,const變數在執行時期,也是一種變數,系統會為其分配記憶體.
由於#define 定義的巨集常量是全域性的,不能達到目的,於是想當然地覺得應該用 const 修飾資料成員來實現。const 資料成員的確是存在的,但其含義卻不是我們所期望的。const 資料成員只在某個物件生存期內是常量,而對於整個類而言卻是可變的,因為類可以建立多個物件,不同的物件其 const 資料成員的值可以不同。
不能在類宣告中初始化 const 資料成員。以下用法是錯誤的,因為類的物件未被建立時,編譯器不知道 size 的值是什麼。
class a
; const 資料成員的初始化只能在類建構函式的初始化表中進行,例如
**變數可以在建構函式的函式體中初始化
class a
; a::a(int size) : size(size) // 建構函式的
a a(100); // 物件 a 的 size 值為 100
a b(200); // 物件 b 的 size 值為 200
怎樣才能建立在整個類中都恆定的常量呢?以下介紹兩種方法:
1.用類中的列舉常量來實現。例如
class a
; // 列舉常量
int array1[size1];
int array2[size2];
}; 列舉常量不會占用物件的儲存空間,它們在編譯時被全部求值。列舉常量的缺點是:它的隱含資料型別是整數,其最大值有限,且不能表示浮點數(如 pi=3.14159)。
2.使用關鍵字static:
class a
這將建立乙個名為size的常量,該常量將與其他靜態變數儲存在一起,而不是儲存在某個物件中。因此,此常量將被整個類的所有物件共享。
三、inline與#define
盡量用inline,不解釋
Effective C 條款02 不止於此
盡量以const,enum,inline替換 define eg 解決方案 const 3.5 另外說說,定義常指標,倘若指標常量不變則寫兩遍const,通常被寫在標頭檔案中 const char const chname bobobo 但是不如用std string const std strin...
Effective C 經驗條款
高效c 4 必須返回物件時,別妄想返回其reference 這句話什麼意思呢?就是在乙個函式內,如果你需要這個函式返回乙個新的物件,那麼這個函式的返回值型別就不要定義成引用型別。就直接返回這個類型別。首先,我們知道在函式傳遞引數時,傳遞引用的好處,尤其是對那麼比較大的型別,但是對於內建型別和stl的...
effective c 條款總結
條款1 盡量用const 和inline 而不用 define 條款2 盡量用而不用 條款3 盡量用new delete 而不用malloc free 條款4 盡量使用c 風格注釋 條款5 對應的new和delete 都要採用相同的形式 條款6 析構函式裡對指標成員呼叫delete條款 條款7 預先...