1.1.1. #運算子
#字元在#define巨集定義中是乙個將引數名轉換為字串的運算子,#放在巨集引數的前面。例如:
#include
#include
#define declare_non_copiable_begin(cname) /
class cname /
public: /
virtual std::string tostring( void )const /
private: /
cname(const cname&); /
cname& operator=(const cname&);
#define declare_non_copiable_end(cname) };
declare_non_copiable_begin(socket)
public:
socket( void )
declare_non_copiable_end(socket)
int main( void )
socket sock;
std::cout<
<
return 0;
先定義了一對巨集,declare_non_copiable_begin和declare_non_copiable_end,在前乙個巨集中將拷貝建構函式和複製運算子定義為private,避免物件進行複製(例如檔案、socket等資源),並定義了乙個預設的tostring函式返回類的名稱,類名稱字串就是通過#運算子生成的。接下來使用定義的巨集定義了乙個socket類,來展示這對巨集的用法。當然這種實現方式不一定是最好的,還可以通過定義乙個基類來實現這種方式,在講到拷貝建構函式時會展示另一種方案。
1.1.2. ##運算子
在#define定義的巨集中,##運算子用於將引數與識別符號連線,構成新的識別符號,但##運算子放在乙個識別符號的最前面,也不能放到識別符號的最後。例如:
#include
#define declare_bit(n) const unsigned int bit ## n = 1<
declare_bit(0); // 等價於:const unsigned int bit0 = 1<<0;
declare_bit(1);
declare_bit(2);
declare_bit(3);
declare_bit(4);
declare_bit(5);
declare_bit(6);
declare_bit(7);
int main( void )
std::cout<<"bit0:"<
<<", bit1:"<
<<", bit2:"<
<<"... bit7:"<
<
return 0;
上面的**先定義了乙個巨集declare_bit,該巨集用於定義整數中各位的權值,然後使用該巨集定義了一系列位的權值。這樣的**更利益於維護,比如我們隨時可以修改實現的機制,此處是通過定義常量實現的,我們隨時可以修改常量的型別,而且只需修改一行**。
注意:需要注意的是c++標準並沒有定義##運算子與#運算子的處理順序,所以不要定義依賴於這兩個運算子解析順序的巨集,避免在不同編譯器下產生不同的結果,這樣的bug往往非常難以定位。
c語言 巨集中 的用法(續)
如下 不明覺厲。define ext2 debug f,a.特別是其中printf f,a 這樣的用法。google之後在stackoverflow找到了這個問題以及解答。詳細的解答跳轉到了gnu的gcc文件 譯文如下 3.6 variadic macros 可變引數的巨集 乙個巨集可以像乙個函式一...
巨集定義中的續行符
巨集定義中的續行符 巨集定義規定,巨集定義必須在一行裡完成。所以用 define定義巨集定義時,有時為了閱讀方便,就加續行符 來換行。在普通 行後面加不加都一樣 vc是自動判斷續行的 例如 define somefun x,a,b if x x a b else x a b 這一行定義是沒有問題的,...
c 中的續行符 和巨集定義的結合使用
c 中經常遇到巨集定義 巨集定義要求的是一行完成 但是一般宣告帶有引數列表的巨集定義的時候,由於函式體字串太長,導致很長不能直觀的看出來,如果自動換行又影響了一行完成的規定 所以誕生了續行符。define somefun x,a,b if x x a b else x a b 這一行定義是沒有問題的...