const 内联 枚举 宏
const 常量
??程序運行時在常量表中,系統為它分配內存,在堆棧分配了空間;const常量有數據類型;語句末有分號;有類型檢查;可以限制范圍 //將所有不希望改變的變量加const修飾
const int a = 1;在類中定義并初始化const變量是不合法的
static QString CC_VERTICAL_LINE("TEX_PNG_BUHIN_01_12"); //靜態變量也是只能在類中定義不能初始化
static const int a = 1;const static char *LogTag = "ScreenOff"; //只有靜態const變量才可以在類中聲明定義,非靜態常量都只能在類中聲明定義,在構造函數中初始化
普通變量可以在類中聲明與定義,在構造函數中進行初始化,靜態成員是"類級別的",也就是它和類的地位相同,而普通成員是"對象級別(即類的實例化級別)".類級別的成員先于該類任何對象的存在而存在,
它被該類所有對象共享,可以推測一下:現在要實例化一個對象,那么靜態變量是需要包含在這個對象里的對吧,假設是實例化對象的時候才定義這個變量,那么若是此時另一個線程也要創建這個類的對象,
若假設成立,則產生問題:1. 靜態變量的重復定義 2.?即使不產生重復定義,那么也會產生競爭,造成死鎖,從而無法成功創建對象,所以:普通靜態成員需要在類中聲明與定義,在類外初始化
內聯
定義:是用inline關鍵字修飾的函數,目的是為了消除函數調用時的時間開銷,從源代碼層看,內聯函數它有函數的結構,而在編譯后,卻不具備函數的性質,內聯函數不是在調用時發生控制轉移,
而是在編譯時將函數體嵌入在每個調用處
特點:是在被調用的地方被展開而不生成執行代碼
優點:既保持預處理宏的效率又增加安全性,還能像一般成員函數一樣可以在類里訪問自如
條件:1.遞歸函數不能定義為內聯函數 2. 內聯函數一般適合于不存在while和switch等復雜的結構且只有1~5條語句的小函數上,否則編譯系統將該函數視為普通函數
3. 內聯函數只能先定義后使用,否則編譯系統也會把它認為是普通函數 4.?對內聯函數不能進行異常的接口聲明 5.?定義了靜態變量的函數不能成為內聯函數
inline:函數如果定義在類中,那么會自動被認為是申請成為內聯函數,如果在類外,那么需要加關鍵字inline對編譯器進行申請,在類外定義的函數如果不加inline關鍵字,那么一定不是內聯函數,
inline關鍵字是對編譯器的一個申請,能不能成為內聯函數,還要看編譯器對該函數定義的具體處理;在類中定義的時候必須把函數體和聲明結合在一起;主張所有的內聯函數都定義在類外,
用inline關鍵字聲明,這樣可以減少混亂。
遞歸函數:如果一個函數調用了它自身,不管是直接的還是間接的,都稱該函數為遞歸函數
例如:求一個變量val的階乘
int factorial(int val) {
if (val > 1) { // 遞歸條件
return factorial(val -1)*val; //遞歸語句
}
else {
return 1; //遞歸結束條件
}
枚舉
定義:枚舉是C++的一種派生數據類型,它是由用戶定義的若干枚舉常量的集合
特點:在編譯的時候確定其值,可以一次定義大量相關的常量,枚舉可以被限制名字空間,類內部,值會自動加1,如果沒設初值,那么會從0開始,枚舉有類型,因為其存儲方式與int相似,所以枚舉值可以
當做int型使用,但使用時最好還是進行強制類型裝換?
例子:兩個不同類型的枚舉值之間需要先進行類型轉換,再進行比較
enum Colors {Red, Green, Blue, Yellow} //枚舉值的定義最好使用十六進制,因為十六進制轉換為二進制會更快
(int)Colors.Red //枚舉值轉換為int 現在最好使用新式轉換, int i = static_cast<int>(Color.Red)
枚舉值可以當做int型使用,如 enum {Number = 5;} ?int scores[Number];
枚舉在QT中的使用:
如果是使用的C++&&QML混合編程,且希望在qml中使用C++定義的枚舉,需要做如下幾步:
1. 在類中開始的地方用Q_ENUMS(Name)注冊進QT元對象系統
2. 在構造與析構之前對枚舉進行定義
之后在QML中使用的時候形式如 ?類名.枚舉變量
宏
宏定義: 宏即宏替換,在C語言源程序中允許用一個標識符來表示一個字符串,稱為宏,關鍵字 define,在所有使用到宏的地方都只是直接的替換而不做任何類型檢查
宏替換是C提供的三種預處理功能的其中一種,這三種預處理包括:宏定義,文件包含,條件編譯,C++繼承C的遺產,在C++中也可以使用宏,宏不能訪問對象的私有成員,
宏的定義很容易產生二義性
特點:在預處理階段對宏定義的替換,使用時要特別小心;宏本身不占用內存單元,但每次調用都分配內存;語句的最后不加分號;無數據類型;非常量,只是盲目替換;是全局的?
使用:(1) 防止頭文件被重復包含?
? #ifndef COMDEF_H //#:字符串化運算符,在一個預處理器宏中的參數前面使用#,預處理器會把這個參數轉換為一個字符數組,并把這一點與沒有插入標點符號的若干個
? #define?COMDEF_H //字符數結合而鏈接成一個單獨的字符數組,能夠生成一個十分方便的宏用于調試期間打印出變量的值
? ...... //中間可以有任意個空格,串一但開始,僅由一新行結束,宏名定以后,即可成為其他宏名定義中的一部分;
#endif? //宏替換僅僅是以文本串代替宏標識符,前提是宏標識符必須獨立的識別出來,否則不進行替換,如果串長于一行,可以在該行末尾用反斜杠'\'續行
(2) 重新定義一些類型,防止由于各種平臺和編譯器的不同,而產生的類型字節數差異,方便移植
typedef unsigned char boolean; /*Boolean value type */
typedef unsigned long int uint32;? ?/*Unsigned 32 bit value */
typedef signed char int8; ? /*Signed 8 bit value */
typedef signed long int int32 ? /*Signed 32 bit value */
(3) 得到指定地址上的一個字節或字 //為防止出現包含錯誤,所有的參數都要用小括號包含
#define MEM_B(x) (*((byte *)(x))) //字節
#define MEM_W(x)?(*((word *)(x))) //字
? (4) 求最大值和最小值
#define MAX(x, y) ((x)>(y)?):(x):(y) //最大值
#define MIN(x, y) ((x)<(y)?):(x):(y) //最小值
(5) 判斷字符是不是十進制的數字
#define DECCHK(c) ?((c) >='0' && (c) <= '9')
(6) 使用一些宏跟蹤調試?
ANSI標準說明了五個預定義的宏名:__LINE__,__FILE__,__DATE__,__TIME__,__STDC__
__LINE__:存放當前行號的整型字面值;
__FILE__:存放文件名的字符串字面值;
__DATE__:存放文件編譯日期的字符串字面值
__TIME__:存放編譯時間的字符串字面值
__STDC__:當要求程序嚴格遵循ANSI C標準時該標識被賦值為1;
? __FUNCTION__ 當前所在函數名
(7) 關于#和##,#的功能是將其后面的宏參數進行字符串化操作,簡單說就是對它所引用的宏變量通過替換后在其左右各加一個雙引號
##被稱為連接符,用來將兩個Token連接為一個Token,它允許設兩個標識符并把它們粘貼在一起自動產生一個新的標識符
#define COMMAND(NAME) {#NAME,NAME##_command}
例子:define FILED(a) char *a##_string; int a##_size
class Record {
FIELD(one);
FIELD(two);
FIELD(three);
...
};
? 每次調用FIELD()宏,將產生一個保存字符串數組的標識符和另一個保存字符數組長度的標識符,它不僅易讀而且消除了編碼出錯,使維護更容易?
#define ChECK_NULLPTR_IQA(p)\ //: \必不可少,表示一句沒寫完,是用來續行的
if (NULL == p) {\
NGLogDebug("IQA", "%s Memory allocation failed!", __PRETTY_FUNCTION__);\
return;\?
}\
else {\
NGLogDebug("IQA", "%s Memory allocation success ! p = %p", __PRETTY_FUNCTION__, p);\
}
實際調用中會出現下面所示的替換過程
#define CHECK_NULLPTR_IQA(m_pFCSettingModel);
if (NULL == m_pFCSettingModel) {
NGLogDebug("IQA", "%s Memory allocation failed!", __PRETTY_FUNCTION__);
return;
}
else {
NGLogDebug("IQA", "%s Memory allocation success ! m_pFCSettingModel?= %p", __PRETTY_FUNCTION__, m_pFCSettingModel);\
}
? (8) 宏定義字符串
#define DEMO_TEST? QString("Demo_Test") //定義的宏替換之后是QString類型的字符串
#define FLAG (2) //定義的FLAG替換之后就是(2),加個括號感覺不錯
#define DEMO_TEST “Demo_Test” //定義的宏替換之后是std::basic類型的字符串
轉載于:https://www.cnblogs.com/qianqiannian/p/6043870.html
總結
以上是生活随笔為你收集整理的const 内联 枚举 宏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库的流程,制度,安全优化
- 下一篇: JDBC链接oracle已经mysql的