zzVC++中常見關鍵字—C++基礎篇

轉載自 [url]http://www.cnblogs.com/luyinghuai/archive/2008/06/28/1230375.html[/url]

“__declspec”是Microsoft c++中專用的關鍵字,它配合着一些屬性可以對標準C++進行擴充。這些屬性有:align、allocate、deprecated、 dllexport、dllimport、 naked、noinline、noreturn、nothrow、novtable、selectany、thread、property和uuid。

1,_declspec
(1)用法一定義接口

#include <IOSTREAM>
using namespace std;

#define interface class __declspec(novtable)

interface ICodec
{
public:
    virtual bool Decode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen);
    virtual bool Encode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen);
};

ICodec 同等於如下:
class ICodec
{
public:
    virtual bool Decode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen)=0;
    virtual bool Encode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen)=0;
};
2,用法二,定義類的屬性
屬性,是面向對象程序設計中不可缺少的元素,廣義的屬性是用來描述一個對象所處於的狀態。而我們這篇文章所說的屬性是狹義的,指能用“=”操作符對類的一個數據進行get或set操作,而且能控制get和set的權
#include <IOSTREAM>
#include <map>
#include <string>
#include <CONIO.H>
using namespace std;

class propertytest
{
    int m_xvalue;
    int m_yvalues[100];
    map<string,string> m_zvalues;
public:
    __declspec(property(get=GetX, put=PutX)) int x;
    __declspec(property(get=GetY, put=PutY)) int y[];
    __declspec(property(get=GetZ, put=PutZ)) int z[];

    int GetX()
    {
        return m_xvalue;
    };
    void PutX(int x)
    {
        m_xvalue = x;
    };
   
    int GetY(int n)
    {
        return m_yvalues[n];
    };

    void PutY(int n,int y)
    {
        m_yvalues[n] = y;
    };

    string GetZ(string key)
    {
        return m_zvalues[key];
    };

    void PutZ(string key,string z)
   {
       m_zvalues[key] = z;
    };

};

int main(int argc, char* argv[])
{
    propertytest test;
    test.x = 3;
    test.y[3] = 4;
    test.z["aaa"] = "aaa";
    std::cout << test.x <<std::endl;
    std::cout << test.y[3] <<std::endl;
    std::cout << test.z["aaa"] <<std::endl;

   getch();
   return 0;
}

3,用法三,
_declspec(dllimport)     是說這個函數是從別的DLL導入。我要用。
_declspec(dllexport)   是說這個函數要從本DLL導出。我要給別人用。
#define Test_API __declspec(dllexport)

Class test
{
   public:
   Test_API HRESULT WINAPI Initialize(LPCTSTR filename);
}

4. __declspec(align(16)) struct SS{ int a,b; };
 它與#pragma pack()是一對兄弟,前者規定了對齊的最小值,後者規定了對齊的最大值。同時出現時,前者優先級高。 __declspec(align())的一個 特點是,它僅僅規定了數據對齊的位置,而沒有規定數據實際佔用的內存長度,當指定的數據被放置在確定的位置之後,其後的數據填充仍然是按照#pragma pack規定的方式填充的,這時候類/結構的實際大小和內存格局的規則是這樣的:在__declspec(align())之前,數據按照#pragma pack規定的方式填充,如前所述。當遇到__declspec(align())的時候,首先尋找距離當前偏移向後最近的對齊點(滿足對齊長度爲max (數據自身長度,指定值)),然後把被指定的數據類型從這個點開始填充,其後的數據類型從它的後面開始,仍然按照#pragma pack填充,直到遇到下一個__declspec(align())。當所有數據填充完畢,把結構的整體對齊數值和__declspec(align ())規定的值做比較,取其中較大的作爲整個結構的對齊長度。 特別的,當__declspec(align())指定的數值比對應類型長度小的時候,這 個指定不起作用。
5. #pragma section("segname",read)
    \ __declspec(allocate("segname")) int i = 0;
    \ int main(){ return 1;};
 此關鍵詞必須跟隨code_seg,const_seg,data_seg,init_seg,section關鍵字之後使用,以上例子使用了section關鍵字。使用此關鍵字將告知編譯器,其後的變量間被分配在那個數據段。
6. __declspec(deprecated(MY_TEXT)) void func(int) {}
 與pragma deprecated()相同。此聲明後,如果在同一作用域中使用func(int)函數,將被提醒c4996警告。
7. __declspec(jitintrinsic)
 用於標記一個函數或元素爲64位公共語言運行時。具體用法未見到。
8. __declspec( naked ) int func( formal_parameters ) {}
 此關鍵字僅用於x86系統,多用於硬件驅動。此關鍵字可以使編譯器在生成代碼時不包含任何註釋或標記。僅可以對函數的定義使用,不能用於數據聲明、定義,或者函數的聲明。
9. __declspec(restrict) float * init(int m, int n) {};
   & __declspec(noalias) void multiply(float * a, float * b, float * c) {};// 優化必用!
 __declspec (restrict)僅適用於返回指針的函數聲明,如 __declspec(restrict) void *malloc(size_t size);restrict declspec 適用於返回非別名指針的函數。此關鍵字用於 malloc 的 C 運行時庫實現,因爲它決不會返回已經在當前程序中使用的指針值(除非您執行某個非法操作,如在內存已被釋放之後使用它)。restrict declspec 爲編譯器提供執行編譯器優化的更多信息。對於編譯器來說,最大的困難之一是確定哪些指針會與其他指針混淆,而使用這些信息對編譯器很有幫助。有必要指出, 這是對編譯器的一個承諾,編譯器並不對其進行驗證。如果您的程序不恰當地使用 restrict declspec,則該程序的行爲會不正確。 __declspec(noalias)也是僅適用於函數,它指出該函數是半純粹的函數。半純粹的函數是指 僅引用或修改局部變量、參數和第一層間接參數。此 declspec 是對編譯器的一個承諾,如果該函數引用全局變量或第二層間接指針參數,則編譯器會生成將中斷應用程序的代碼。
10. class X {
   \ __declspec(noinline) int mbrfunc() { return 0; /* will not inline*/ };
 在類中聲明一個函數不需要內聯。
11. __declspec(noreturn) extern void fatal () {}
 不需要返回值。
12. void __declspec(nothrow) __stdcall f2();
 不存在異常拋出。
13. struct __declspec(novtable) X { virtual void mf(); };
    \ struct Y : public X {void mf() {printf_s("In Y\n");}};
 此關鍵字標記的類或結構不能直接實例化,否則將引發AV錯誤(access violation)。此關鍵字的聲明將阻止編譯器對構造和析構函數的vfptr的初始化。可優化編譯後代碼大小。
12. struct S {   int i;
    \ void putprop(int j) {  i = j; }
    \ int getprop() { return i; }
    \ __declspec(property(get = getprop, put = putprop)) int the_prop;};
  此關鍵字與C#中get & set屬性相同,可定義實現針對一個字段的可讀或可寫。以上例子,可以使用(如果實例化S爲ss)如:ss.the_prop = 156;(此時,ss.i == 156)接着如果:cout<< s.the_prop;(此時將調用getprop,使返回156)。
14. __declspec(selectany)(轉)
 在MFC,ATL的源代碼中充斥着__declspec (selectany)的聲明。selectany可以讓我們在.h文件中初始化一個全局變量而不是隻能放在.cpp中。比如有一個類,其中有一個靜態變 量,那麼我們可以在.h中通過類似__declspec(selectany) type class::variable = value; 這樣的代碼來初始化這個全局變量。既是該.h被多次include,鏈接器也會爲我們剔除多重定義的錯誤。對於template的編程會有很多便利。
15. __declspec(thread) int in_One_Thread;
 聲明in_One_Thread爲線程局部變量並具有線程存儲時限,以便鏈接器安排在創建線程時自動分配的存儲。
16. struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
 將具有唯一表示符號的已註冊內容聲明爲一個變量,可使用__uuidof()調用。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章