c++中的explicit關鍵字用來修飾類的建構函式,表明該建構函式是顯式的,既然有"顯式"那麼必然就有"隱式",那麼什麼是顯示而什麼又是隱式的呢?
如果c++類的建構函式有乙個引數,那麼在編譯的時候就會有乙個預設的轉換操作:將該建構函式對應資料型別的資料轉換為該類物件,如下面所示:
class myclass
....
myclass obj = 10; //ok,convert int to myclass
在上面的**中編譯器自動將整型轉換為myclass類物件,實際上等同於下面的操作:
myclass temp(10);
myclass obj = temp;
上面的所有的操作即是所謂的"隱式轉換"。
如果要避免這種自動轉換的功能,我們該怎麼做呢?嘿嘿這就是關鍵字explicit的作用了,將類的建構函式宣告為"顯示",也就是在宣告建構函式的時候前面新增上explicit即可,這樣就可以防止這種自動的轉換操作,如果我們修改上面的myclass類的建構函式為顯示的,那麼下面的**就不能夠編譯通過了,如下所示:
class myclass
....
myclass obj = 10; //err,can't non-explict convert
mutable關鍵字
關鍵字mutable是c++中乙個不常用的關鍵字,他只能用於類的非靜態和非常量資料成員我們知道乙個物件的狀態由該物件的非靜態資料成員決定,所以隨著資料成員的改變,對像的狀態也會隨之發生變化!
如果乙個類的成員函式被宣告為const型別,表示該函式不會改變物件的狀態,也就是該函式不會修改類的非靜態資料成員.但是有些時候需要在該類函式中對類的資料成員進行賦值.這個時候就需要用到mutable關鍵字了
例如:class demo
~demo(){}
public:
bool getflag() const
private:
int m_naccess;
bool m_bflag;
};int main()
編譯上面的**會出現 error c2166: l-value specifies const object的錯誤說明在const型別的函式中改變了類的非靜態資料成員.這個時候需要使用mutable來修飾一下要在const成員函式中改變的非靜態資料成員
m_naccess,**如下:
class demo
~demo(){}
public:
bool getflag() const
private:
mutable int m_naccess;
bool m_bflag;
};int main()
這樣再重新編譯的時候就不會出現錯誤了!
volatile關鍵字
volatile關鍵字是一種型別修飾符,用它宣告的型別變數表示可以被某些編譯器未知的因素更改,比如
作業系統、硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的**就不再進行
優化,從而可以提供對特殊位址的穩定訪問。
使用該關鍵字的例子如下:
int volatile nvint;
當要求使用volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指
令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。
例如:volatile int i=10;
int a = i;
。。。//其他**,並未明確告訴編譯器,對i進行過操作
int b = i;
volatile 指出 i是隨時可能發生變化的,每次使用它的時候必須從i的位址中讀取,因而編譯器生成的
彙編**會重新從i的位址讀取資料放在b中。而優化做法是,由於編譯器發現兩次從i讀資料的**之間
的**沒有對i進行過操作,它會自動把上次讀的資料放在b中。而不是重新從i裡面讀。這樣以來,如果
i是乙個暫存器變數或者表示乙個埠資料就容易出錯,所以說volatile可以保證對特殊位址的穩定訪問
注意,在vc6中,一般除錯模式沒有進行**優化,所以這個關鍵字的作用看不出來。下面通過插入彙編
**,測試有無volatile關鍵字,對程式最終**的影響:
首先用classwizard建乙個win32 console工程,插入乙個voltest.cpp檔案,輸入下面的**:
#include
void main()
int b = i;
printf("i= %d/n",b);}
然後,在除錯版本模式執行程式,輸出結果如下:
i = 10
i = 32
然後,在release版本模式執行程式,輸出結果如下:
i = 10
i = 10
輸出的結果明顯表明,release模式下,編譯器對**進行了優化,第二次沒有輸出正確的i值。
下面,我們把 i的宣告加上volatile關鍵字,看看有什麼變化:
#include
void main()
int b = i;
printf("i= %d/n",b);}
分別在除錯版本和release版本執行程式,輸出都是:
i = 10
i = 32
這說明這個關鍵字發揮了它的作用!
__based關鍵字
該關鍵字主要用來解決一些和共享記憶體有關的問題,它允許指標被定義為從某一點開始算的32位偏移值,而不是記憶體中的絕對位置
demostruct __based(lpshare)* lpdemo;
lpdemo=(struct tagdemostruct __based(lpshare) *)((lpbyte)lpshare+0xaaa);
(紅色部分是我加的,在vc++6.0裡面編譯通過,經過測試lpdemo指標的值是0xaaa)
strcpy(lpdemo->sz,"19821006");
上面的例子宣告了乙個指標lpdemo,內部儲存的是從lpshare開始的偏移值,也就是lpdemo是以lpshare為基準的偏移值.上面的例子中的demostruct只是隨便定義的乙個結構,用來代表任意的結構.
雖然__based指標使用起來非常容易,但是,你必須在效率上付出一定的代價.每當你用__based指標處理資料,cpu都必須為它加上基位址,才能指向真正的位置
c 的一些不常見關鍵字
explicit用來防止由建構函式定義的隱式轉換,比如 class base base 10 即base類只有乙個int型別的變數,explicit使用了以後,就不允許這樣寫。被宣告為explicit的建構函式通常比非explicit的建構函式更受歡迎,因為它們禁止編譯器執行非預期的型別轉換。vol...
C 中不常用的關鍵字
mutable關鍵字 關鍵字mutable是c 中乙個不常用的關鍵字,他只能用於類的非靜態和非常量資料成員我們知道乙個物件的狀態由該物件的非靜態資料成員決定,所以隨著資料成員的改變,對像的狀態也會隨之發生變化 如果乙個類的成員函式被宣告為const型別,表示該函式不會改變物件的狀態,也就是該函式不會...
C 幾個不常用的關鍵字
asm 插入乙個彙編指令.auto 宣告乙個本地變數.const cast 從乙個const變數中丟擲.dynamic cast 動態投射.explicit 僅用在構造器的正確匹配.extern 告訴編譯器在別的地方變數已經被定義過了.friend 允許非函式成員使用私有資料.inline 定義乙個...