盡量以const、enum和inline代替#define
一、#define的功能
參考:http://www.crifan.com/_define_detailed/
(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 int SIZE = 100; // 錯誤,企圖在類聲明中初始化 const 數據成員
int array[SIZE]; // 錯誤,未知的 SIZE
};
const 數據成員的初始化只能在類構造函數的初始化表中進行,例如
**變量可以在構造函數的函數體中初始化
class A
{
A(int size); // 構造函數
const int SIZE ;
};
A::A(int size) : SIZE(size) // 構造函數的
{
}
A a(100); // 對象 a 的 SIZE 值為 100
A b(200); // 對象 b 的 SIZE 值為 200
怎樣才能建立在整個類中都恆定的常量呢?以下介紹兩種方法:
1.用類中的枚舉常量來實現。例如
class A
{
enum { SIZE1 = 100, SIZE2 = 200}; // 枚舉常量
int array1[SIZE1];
int array2[SIZE2];
};
枚舉常量不會占用對象的存儲空間,它們在編譯時被全部求值。枚舉常量的缺點是:它的隱含數據類型是整數,其最大值有限,且不能表示浮點數(如 PI=3.14159)。
2.使用關鍵字static:
class A
{
static const int SIZE=100;
int array[SIZE];
}
這將創建一個名為SIZE的常量,該常量將與其他靜態變量存儲在一起,而不是存儲在某個對象中。因此,此常量將被整個類的所有對象共享。
三、inline與#define
盡量用inline,不解釋