這篇文章我們講一下C++當中的宏。其實接觸過大型項目的朋友可能都被詭異的宏折磨過。
宏是在預處理當中,通過文本替換的方式來實現一些操作,這樣可以不用反復的輸入代碼,幫助我們實現自動化。至于預處理的過程,其實就是文本編輯,這個在之前的文章中有提到過。
替換的具體內容,可能是普通文本,也可以是參數變量等各種東西,可以說,就沒有什么是不能夠被宏替換掉的,我們可以拿來替換非常復雜的內容。但是需要注意的是,我們不希望拿宏來替換太多與C++特性有關的代碼,這樣并不是一個好的做法,因為會降低代碼的可讀性,雖然這樣做是沒有任何問題的。
舉個例子,我們用宏替換到我們常用的cin.get()語句:
#include<iostream>
#include<string>
#define WAIT std::cin.get()int main() {std::cout << "Hello World!" << std::endl;WAIT;
}
這樣寫當然是可以的,是能夠編譯通過的,但是這種寫法是很傻的。因為cin.get()是非常常用的語句,但是使用一個WAIT來替換它,反而會降低代碼的可讀性,讓其他人看得一頭霧水。
當然,分號也可以是宏的一部分,如果想的話也可以把分號寫在宏里面,那么就不用在代碼里面再寫分號了。
接下來我們看看如何在宏當中定義函數。
#include<iostream>
#include<string>
#define LOG(x) std::cout<< x << std::endl;int main() {LOG("Hello World!")std::cin.get();
}
我們運行代碼就會發現,我們正常的完成了打印,所以和實際寫cout效果是一樣的。
那么我們可以如何用宏幫助我們?一個有趣的實例就是在我們的日志類當中,我們希望在debug狀態下打印出我們需要的信息,但是在release版本當中不希望那么多東西都被打印到控制臺上,那么如何能夠區分debug還是release?在不同模式下函數應該是什么樣子的?這些我們就都可以用到宏來進行控制。
首先我們需要打開屬性,然后找到預處理界面,然后分別為debug和release兩個配置添加不同的宏,如圖所示:
我們在debug和release模式下分別定義PR_DEBUG和PR_RELEASE兩個宏,這樣我們就有了區分debug和release兩個模式的工具。然后我們就可以通過宏來控制我們是否需要打印:
#ifdef PR_DEBUG
#define LOG(x) //這里填寫我們需要的函數定義
#else
#define LOG(x)
#endif
如上述代碼所示,我們可以在debug模式下讓LOG函數真的為我們輸出一些東西,但是在release模式下,LOG就不代表任何代碼了,也就是說切換到release時,LOG處都會變成空白,宏自動的為我們刪除了在release時需要被刪除的代碼,這一點是非常nice的。
但是這樣使用也是有一點問題的,因為有的時候我們不想使用某個宏了,那我們還得去刪除,就很麻煩,最好的情況是給宏賦一個值,然后我們不想使用宏的時候,可以直接修改這個宏的值,那么這個宏就被禁用了。首先我們在設置當中為我們的宏賦值:
如圖所示,我們把PR_DEBUG賦值為1,然后我們在代碼當中可以直接這樣寫:
#if PR_DEBUG == 1
來判斷是不是在debug模式下。如果我們想要禁用這個宏,只需要
#define PR_DEBUG 0
就可以禁用這個宏了。
除此之外,我們還可以用宏來禁用一整塊代碼,如下所示:
#if 0LOG("Hello World!")
#endif
這樣中間部分代碼就都無效了。
如果我們想要代替多行代碼,可以用反斜線 \ 來替代,反斜線就是分行的轉義。
宏最常用的地方就是用來幫助我們debug,還可以自動查錯,也可以幫助跟蹤內存的使用情況。但是如果濫用宏,確實會導致代碼可讀性大幅降低,所以我們還是要慎重使用宏。以上就是本文的全部內容了,希望大家喜歡!