青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

VC++ 6.0的小花招

Visual Studio系列中產品中,Visual Studio 6.0是最經典的一個版本,雖然后來有Visual Studio .NET 2003,以及2005,也確實添加了很多讓我覺得激動的特性,但是從使用細節的細膩程度上來看,VS 6.0無疑是最棒的。我們一些同事甚至試圖把2005C++編譯器獨立的拿到Visual Studio 6.0中來用,也不愿意升級到.NET上來用,可見其魅力。

 

VS 6.0這個產品的成熟相比,VC++ 6.0的編譯器的的確確相對來說有些糟糕,其中最被詬病的是對模板技術支持很不好。下面我想做的一件事情,就是向那些繼續留戀VC++ 6.0的朋友,介紹一些小花招,來避開VC++ 6.0的一些編譯器缺陷。

 

 

1for (type var=expression;;) 中變量var的作用域問題。

 

按照C++標準,這里定義的變量var出了for循環應該被銷毀。也就是說下面這段代碼是有效的:

 

   for (int i = 0; i < 100; ++i)

       func();

   for (int i = 0; i < 100; ++i)

       func2();

 

而下面這段代碼應該編譯不過:

 

    for (int i = 0; i < 100; ++i)

    {

         if (has_found_it())

         {

             handle_find_result();

             break;

          }

    }

    if (i == 100)

         do_not_found();

 

然而VC++ 6.0對于第一段代碼會報變量i重復定義錯誤,而第二段代碼編譯通過。

 

為了讓VC++ 6.0for語句看起來符合C++標準,你可以這樣做:

 

   #define for if (0); else for

 

你會發現很有趣,這樣define一下后,VC++ 6.0for語句完全符合C++標準了!而且由于編譯器的優化,Release版本不會增加任何額外的開銷。

 

喜歡鉆牛角尖的朋友可能會說:嗯,不錯的主意。但是——為什么不這樣做:

 

   #define for if (1) for

 

嗯?看起來也可以。還是讓我們看一個用例:

 

   if (cond)

      for (int i = 0; i < 100; ++i)

          func1();

   else

       func2();

 

進行宏代碼展開后,成為:

 

   if (cond)

       if (1)

           for (int i = 0; i < 100; ++i)

               func1();

       else

           func2();

 

這個結果顯然不能符合我們的原意。這里func2();語句永遠得不到執行機會。

 

 

2)模板參數類型如果不出現在參數列表中,則不能作為返回值類型。

 

由于編譯器的缺陷,VC++ 6.0不支持以下這種用法:

 

   template <class T1, class T2>

   T1 func(T2 arg)

   {

       T1 var;

       ... // 處理var過程

       return var;

   }

 

   void test()

   {

       int result1 = func<int>(1);

       double result2 = func<double>(2);

   };

 

很抱歉,這種用法VC++ 6.0不支持。讓人惱火的是,VC++ 6.0編譯時不會提示錯誤,但是生成的執行代碼卻很成問題。

 

究其原因,是因為VC++ 6.0template技術是在編譯器的較高層次做的,真正的編譯器核心并不考慮模板。以上面的代碼為例,對編譯器核心來說,只是有兩個重載函數而已:

 

   int func(int arg);

   double func(int arg);

 

如果是普通情況,只是返回值不同的函數,是不能同時存在的,編譯器應該認為這是一個錯誤。但是很在模板情況下,這兩個函數被簡單認為是同一個函數。因為VC++ 6.0會為每個函數根據它的:

   1)所在的namespace

   2)所在的類的類名(如果是成員函數);

   3)函數名;

   4)函數調用方式(cdeclstdcall還是fastcall);

   5)所有參數的類型;

而生成一個唯一標識該函數的函數名。這個過程叫Name Mangling,是所有C++編譯器都要進行的工作。而另一個背景是,很多C++編譯器生成的目標文件(.obj文件)有一些和模板相關的特殊信息,包括也標識了某個函數是否模板函數。這是因為一個模板函數在多個源文件(.cpp文件)中被調用的話,這個模板函數就會在這些源文件編譯生成的目標文件(.obj文件)中都定義(definition)一份。為了支持模板,link程序顯然必須知道這個函數是模板函數,從而隨意選擇一個定義(丟棄其余的定義),而不是報符號重復定義錯誤。

 

因為函數名、參數列表等完全一致,所以這兩個函數Name Mangling后生成的名字是一樣的,并且,它們都被標識為這是模板函數。從而,link程序在工作的時候,簡單地將其中一個函數定義給拋棄了。

 

那么,如果我們非要提供上述的func函數,怎么辦?我們來點花招:

 

template <class T1>

class func

{

private:

    T1 var;

 

public:

    template <class T2>

    func(T2 arg)

    {

       ... // 處理var過程

    }

    operator T1() const

    {

        return var;

    }

};

 

我們再來使用func這個函數

 

   void test()

   {

       int result1 = func<int>(1);

       double result2 = func<double>(2);

   };

 

呵呵,你會發現,它還真象是你期望的正常工作。

 

 

3)仿真VC++提供的關鍵字__uuidof

 

這個技巧不是針對VC++ 6.0缺陷的,而是針對VC++擴展語法的。這個技巧的來由,是為了某些希望有一天有可能要脫離Visual C++環境進行開發的人員。為了脫離VC++,你需要謹慎使用它的所有擴展語法。例如本文討論的__uuidof。我們先來看看一個例子:

 

class __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BA")) Class;

struct __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BB")) Interface;

 

void test()

{

   CLSID clsid = __uuidof(Class);

   IID iid = __uuidof(Interface);

   ...

}

 

這比起你以前定義uuid的方法簡單多了吧?可惜,這樣好用的東西,它只在VC++中提供。不過沒有關系,我們這里介紹一個技巧,可以讓你在幾乎所有C++編譯器中都可以這樣方便的使用__uuidof。這里沒有說是所有,是因為我們使用了模板特化技術,可能存在一些比較古老C++編譯器,不支持該特性。

 

也許你已經迫不及待了。好,讓我們來看看:

 

#include <string>

#include <cassert>

 

inline

STDMETHODIMP_(GUID) GUIDFromString(LPOLESTR lpsz)

{

    HRESULT hr;

    GUID guid;

    if (lpsz[0] == '{')

    {

        hr = CLSIDFromString(lpsz, &guid);

    }

    else

    {

        std::basic_string<OLECHAR> strGuid;

        strGuid.append(1, '{');

        strGuid.append(lpsz);

        strGuid.append(1, '}');

        hr = CLSIDFromString((LPOLESTR)strGuid.c_str(), &guid);

    }

    assert(hr == S_OK);

    return guid;

}

 

template <class Class>

struct _UuidTraits {

};

 

#define _DEFINE_UUID(Class, uuid)                                        \

template <>                                                              \

struct _UuidTraits<Class> {                                              \

    static const GUID& Guid() {                                          \

        static GUID guid = GUIDFromString(L ## uuid);                    \

        return guid;                                                     \

    }                                                                    \

}

 

#define __uuidof(Class)    _UuidTraits<Class>::Guid()

 

#define DEFINE_CLSID(Class, guid)                                        \

    class Class;                                                         \

    _DEFINE_UUID(Class, guid)

 

#define DEFINE_IID(Interface, iid)                                       \

    struct Interface;                                                    \

    _DEFINE_UUID(Interface, iid)

 

 

這樣一來,就已經模擬出一個__uuidof關鍵字。我們可以很方便進行uuid的定義。舉例如下:

 

DEFINE_CLSID(Class, "{B372C9F6-1959-4650-960D-73F20CD479BA}");

DEFINE_IID(Interface, "{B372C9F6-1959-4650-960D-73F20CD479BB}");

 

void test()

{

   CLSID clsid = __uuidof(Class);

   IID iid = __uuidof(Interface);

   ...

}

 

VC++中,為了與其他編譯器以相同的方式來進行uuid的定義,我們不直接使用__declspec(uuid),而是也定義DEFINE_CLSID, DEFINE_IID宏:

 

#define DEFINE_CLSID(Class, clsid)           \

    class __declspec(uuid(clsid)) Class

 

#define DEFINE_IID(Interface, iid)           \

    struct __declspec(uuid(iid)) Interface

 

這樣一來,我們已經在所有包含VC++在內的支持模板特化技術的編譯器中,提供了__uuidof關鍵字。通過它可以進一步簡化你在C++語言中實現COM組件的代價。

 

附注:關于本文使用的C++模板的特化技術,詳細請參閱C++文法方面的書籍,例如《C++ Primer》。其實這個技巧在C++標準庫——STL中有一個專門的名字:traits(萃取),你可以在很多介紹STL的書籍中見到相關的介紹。

 

posted on 2008-11-09 01:37 肥仔 閱讀(1360) 評論(0)  編輯 收藏 引用 所屬分類: VC 存檔C++ 模板

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧洲一区二区三区在线观看| 久久在线免费观看视频| 亚洲欧美日韩精品综合在线观看| 日韩一区二区福利| 99国产精品久久久久久久成人热| 亚洲精品久久嫩草网站秘色| 亚洲免费观看高清完整版在线观看熊 | 99一区二区| 亚洲一区二区三区视频播放| 性欧美超级视频| 免费成人网www| 亚洲国产欧美在线| 99精品国产福利在线观看免费| 亚洲四色影视在线观看| 久久精品亚洲一区二区| 欧美理论在线播放| 国产一区二区三区高清在线观看 | 日韩一二三在线视频播| 日韩一级黄色av| 亚洲综合国产精品| 久久只有精品| 国产精品美女www爽爽爽| 在线免费观看视频一区| 亚洲午夜视频| 欧美成人资源| 亚洲视频香蕉人妖| 久久视频在线视频| 国产精品网站在线播放| 亚洲国产视频直播| 欧美在线免费一级片| 最新成人av在线| 久久国产精彩视频| 欧美精品一区二区在线播放| 国产一区二区三区在线观看免费| 亚洲午夜激情免费视频| 另类综合日韩欧美亚洲| 日韩视频二区| 老司机免费视频久久| 国产欧美 在线欧美| 亚洲免费精彩视频| 欧美电影免费观看网站| 午夜精品国产更新| 国产精品老牛| 亚洲一区综合| 亚洲国产一区二区三区在线播| 欧美一区二区在线| 国产精品美女主播在线观看纯欲| 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲午夜电影网| 欧美精品三区| 亚洲黄色成人| 欧美激情一区在线| 麻豆精品精品国产自在97香蕉| 国产伦精品一区二区三区高清版 | 久久成人免费电影| 国产精品爽黄69| 午夜日韩电影| 亚洲欧美日韩一区在线观看| 欧美午夜国产| 亚洲欧美日韩国产| 亚洲视频一区二区在线观看| 欧美日本一区| 亚洲综合色丁香婷婷六月图片| 一本色道久久88亚洲综合88 | **性色生活片久久毛片| 久久精品国亚洲| 欧美在线免费视频| 激情五月综合色婷婷一区二区| 久久女同互慰一区二区三区| 久久精品一区二区三区不卡| 黄色资源网久久资源365| 美女视频黄a大片欧美| 狂野欧美激情性xxxx| 国产一区二区三区日韩欧美| 午夜伦欧美伦电影理论片| 亚洲一区二区视频在线| 国产一区视频观看| 老巨人导航500精品| 欧美成人dvd在线视频| 一区二区av在线| 亚洲男同1069视频| 国产午夜精品久久久久久久| 久久久99爱| 欧美国产视频在线观看| 久久综合激情| 免费日韩av电影| 亚洲一区欧美二区| 久久久午夜视频| 一区二区免费在线视频| 西瓜成人精品人成网站| 亚洲国产成人久久综合| 99v久久综合狠狠综合久久| 国产精品一区久久久| 久久久久久一区二区三区| 欧美全黄视频| 免费成人黄色| 欧美性生交xxxxx久久久| 鲁鲁狠狠狠7777一区二区| 欧美视频在线观看 亚洲欧| 久久蜜桃av一区精品变态类天堂| 免费久久99精品国产自| 欧美一区二区三区在线免费观看| 另类亚洲自拍| 亚洲图色在线| 女女同性精品视频| 久久爱另类一区二区小说| 欧美不卡视频一区发布| 久久国产精品免费一区| 欧美精品久久天天躁| 免费短视频成人日韩| 国产女人精品视频| 亚洲乱码国产乱码精品精天堂| 国产日韩欧美综合精品| 亚洲另类在线一区| 狠狠久久亚洲欧美专区| 中文av一区特黄| 亚洲最新视频在线| 久久香蕉精品| 久久婷婷色综合| 国产精品中文字幕在线观看| 亚洲精品看片| 亚洲精品韩国| 久久夜色精品国产噜噜av| 欧美亚洲自偷自偷| 欧美人与性动交cc0o| 欧美成人精品不卡视频在线观看| 国产视频在线观看一区| 99在线精品视频| 亚洲人成网站精品片在线观看| 久久久久久亚洲精品杨幂换脸 | 国产一区91| 亚洲一级黄色片| 亚洲一区二区三区中文字幕在线 | 久久精品国产一区二区三| 小处雏高清一区二区三区 | 亚洲国产精品ⅴa在线观看| 欧美一级二级三级蜜桃| 欧美一级理论性理论a| 国产精品久久久久久久久久三级| 亚洲三级观看| 亚洲一区免费网站| 久久国产精品黑丝| 性欧美长视频| 欧美激情一区二区三区在线视频观看| 久久精品国亚洲| 艳妇臀荡乳欲伦亚洲一区| 国内综合精品午夜久久资源| 欧美aa国产视频| 开心色5月久久精品| 久久av一区二区三区亚洲| 欧美电影免费观看高清| 在线一区二区三区做爰视频网站 | 日韩视频在线观看免费| 久久国产精品毛片| 亚洲精品在线免费观看视频| 久久久青草婷婷精品综合日韩| 久久综合伊人77777蜜臀| 91久久在线播放| 国产精品普通话对白| 国产三级精品三级| 国产精品入口66mio| 欧美 亚欧 日韩视频在线| 欧美亚洲色图校园春色| 亚洲国产日韩美| 亚洲乱码国产乱码精品精| 欧美成人免费小视频| 久久蜜臀精品av| 久久综合999| 美女视频网站黄色亚洲| 久久另类ts人妖一区二区| 久久精品人人爽| 亚洲欧美中文日韩v在线观看| 在线看片欧美| 日韩一区二区精品| 一区二区福利| 亚洲免费在线观看| 尤物九九久久国产精品的分类| 国产亚洲一级| 亚洲区一区二| 亚洲免费观看在线观看| 亚洲三级免费| 亚洲欧美在线高清| 国产嫩草影院久久久久| 久久精品在线观看| 欧美一级播放| 亚洲国产欧美日韩精品| 亚洲国产成人av在线| 欧美 日韩 国产精品免费观看| 欧美日韩不卡| 亚洲精品视频在线| 男人的天堂亚洲| 久久婷婷综合激情| 亚洲精品1区2区| 久久国产色av| 小嫩嫩精品导航| 狠狠操狠狠色综合网| 久久av最新网址| 日韩一级成人av| 91久久在线| 欧美日韩免费观看一区=区三区|