【windows8開發】深入淺出C++/CX )

來源:互聯網
上載者:User
http://blog.csdn.net/my_business/article/details/7497248什麼是C++ /CX? 首先要明白它跟C++ 0x/11以及C++ /CLR是完全不同的東西。C++ 0x/11是目前最新的C++標準庫,而C++ /CX其實是微軟在Win8開發平台下,對C++語言的一種擴充。C++ /CLR是微軟為了C++能在.Net下運行,針對CLR,雖然也是對C++的擴充,但它編譯後是託管於CLR的,屬於Managed C++。而C++ /CX則屬於Native C++,它不使用CLR也沒有記憶體回收機制。雖然C++ /CX有些新文法特性是直接從/CLR借鑒過來的,但是從底層實現上來看,它們是完全不同的兩種擴充。本文會簡單介紹C++ /CX在文法上的一些擴充。
1.實值型別value和參考型別ref
value和ref都是用來定義class的,所以有如下的文法:  [cpp] view plaincopy
  1. ref class Object{};  
  2. value class Object{};  

 兩者有什麼不同?其實參考型別ref類似於Java裡面的引用概念,而實值型別value就是我們通常理解的C++類型。那又為什麼要增加這樣的關鍵字來進行區分呢?原因是不管統一成ref類型還是value類型都有一定缺陷。

類型value的話,在棧上分配空間,效率較高,但是它不支援多態,所以比如作為函數傳回值使用時,有時會存在部分拷貝的問題。其實標準C++裡面都是值
類型value,別說有指標什麼呢,指標本身不過是個整型的地址值,它還是實值型別的,也別跟我說什麼函數參數傳遞有傳值和傳址呢,即使傳址,所傳遞的指標
本身還是以值的形式傳遞的。
而參考型別ref,支援多態,但是它是在堆上分配空間,效率較低,而且會帶來額外引用計數上的開銷。


所以C++ /CX決定把兩者區分開來,讓開發人員根據實際情況是選擇。比如沒必要支援多態的我們可以考慮使用value類型,比如希望交給系統管理引用計數的我們可以考慮使用ref類型。
2. public類C++ /CX裡有這樣的定義: [cpp] view plaincopy

  1. public ref class Object {};  
  2. public value class Object {};  

 用public來定義類,作用其實顯而易見,所有準備對外公開的類必須設為
public,比如組件裡對外公布的類,如果不定義為public的話,外部是訪問不到指定類型的。另外Native
C++類(標準C++裡的類)不能被定義為public,只有ref和value類型的類才可以設定為public,所以下面的代碼編譯會報錯:[cpp] view plaincopy

  1. public class Object {};    // compiler error  
另外還歸納出以下2點:

1. 標準C++方式的類不能被使用在public類的public屬性成員中。
2. public ref類型類的public屬性成員中,除非使用property,否則不能聲明類成員變數。

3. public value類型的類的public屬性成員中,不能聲明類成員變數以外的成員,如函數等。


3. ^符號C++ /CX中,就是用^來表示當前資料類型是ref參考型別。比如有如下class:  [cpp] view plaincopy
  1. ref class SomeObj {  
  2. public:  
  3.      void SomeFunc();  
  4. };  

 那麼在建立這個類對象時,由於是ref參考型別,所以會通過如下方式建立對象:[cpp] view plaincopy

  1. SomeObj^ obj = ref new SomeObj();  
訪問類具體成員對象時使用“->” [cpp] view plaincopy
  1. obj->SomeFunc();  
^的變數代表它是參考型別的,系統會負責他們的引用計數,當引用計數為0時,它們會被銷毀。
4. property可以在public屬性中用property關鍵字來公開類的成員變數,比如:  [cpp] view plaincopy
  1. ref class SomeObj {  
  2. public:  
  3.      property int propertyX;  
  4. };  

 可能你會覺得上面的寫法跟不加property貌似沒有什麼區別,在使用確實上是一樣的,但是用property的方式其實是會去自動產生針對m_propX的預設get(),set()函數,類似下面這樣: [cpp] view plaincopy

  1. ref class SomeObj {  
  2. public:  
  3.    property int propertyX{  
  4.        int get() { return mX; }  
  5.        void set(int x) { mX = x; };  
  6.    }  
  7. private:  
  8.    int mX;  
  9. };  

 那property關鍵字的使用到底有什麼實際意義呢?首先,如果是public定義的類,那麼它的public屬性中只能通過property才能定義成員變數,如下這樣的定義編譯會出錯: [cpp] view plaincopy

  1. public ref class SomeObj {  
  2. public:  
  3.      int mX; // compiler error  
  4. };  

 其次,通過property可以控製成員變數的存取權限,比如唯讀,可讀可寫等,如下代碼就把propertyX設定為唯讀了: [cpp] view plaincopy

  1. ref class SomeObj {  
  2. public:  
  3.      property int propertyX{  
  4.           int get() { return mX; }  
  5.      }  
  6. private:  
  7.    int mX;  
  8. };  

 同時我們還可以自己定義成員變數的讀操作或寫操作,如下代碼把寫操作控製為只會被設定為非0的值: [cpp] view plaincopy

  1. ref class SomeObj {  
  2. public:  
  3.      property int propertyX{  
  4.         int get() { return mX; }  
  5.         void set(int x) {   
  6.             if (x != 0) mX = x;   
  7.         };  
  8.      }  
  9. private:  
  10.      int mX;  
  11. };  
5. 委託delegate和事件event先看delegate的一個執行個體:  [cpp] view plaincopy
  1. delegate void EventHandler(int x);  
  2. ref class WinRTObj sealed  
  3. {  
  4. public:  
  5.      WinRTObj() {  
  6.           eHandler = ref new EventHandler([this](int x) {  
  7.                this->mX = x;  
  8.           });  
  9.      }  
  10.      void FireEvent(int x) {  
  11.           eHandler(x);  
  12.      }  
  13.      EventHandler^ eHandler;  
  14. private:  
  15.      int mX;  
  16. };  

 delegate聲明的EventHandler其實功能就類似於函數指標,在WinRTObj類中我們定義了EventHandler^類型的成員變數,並在建構函式中初始化,new EventHandler時的參數是一個Lambda運算式的匿名函數,所以在FireEvent中調用eHandler(x)時,其實就會去運行這個匿名函數。
我們再把event應用到上面這個例子中,看看event有什麼功能: [cpp] view plaincopy

  1. delegate void EventHandler(int x);  
  2. ref class WinRTObj sealed  
  3. {  
  4. public:  
  5.      WinRTObj() {  
  6.           eHandler += ref new EventHandler([this](int x) {  
  7.                this->mX = x;  
  8.           });  
  9.      }  
  10.      void FireEvent(int x) {  
  11.           eHandler(x);  
  12.      }  
  13.      event EventHandler^ eHandler;  
  14. private:  
  15.      int mX;  
  16. };  

 上面的代碼我們只是在聲明eHandler時用了event關鍵字,同時在建構函式建立eHandler時,把"="改成了"+="。那麼event增加了什麼特性呢?從"+="可以看出,我們可以通過"+="向eHandler添加多個委託,如下所示: [cpp] view plaincopy

  1. WinRTObj() {  
  2.      eHandler += ref new EventHandler([this](int x) {  
  3.    this->mX = x;  
  4.      });  
  5.      eHandler += ref new EventHandler([this](int x) {  
  6.    // ......  
  7.      });  
  8.      eHandler::add(ref new EventHandler([this](int x) {  
  9.    // ......  
  10.      }));  
  11.      auto temp = eHandler::add(ref new EventHandler([this](int x) {  
  12.        
  13.    // ......  
  14.      }));  
  15.      eHandler::remove(temp);  
  16. }  

 從上面的代碼可以看出,除了用"+="來添加委託外,我們還可以用add方法,同時也可以用remove方法刪除已經綁定的委託。現在大家應該明白delegate結合event的具體作用了吧。
6. partial類partial關鍵字也是用來修飾class,它可以讓類可以再多個地方定義同一個類,在編譯的時候會自動合并。比如: [cpp] view plaincopy

  1. partial ref class N   
  2. {  
  3. public:  
  4.    int Method1();  
  5.    static int sData1;  
  6. };  
  7. ref class N   
  8. {     
  9. public:  
  10.      void Method2();  
  11.      int mData2;  
  12. };  

 有什麼用呢?其實在實際開發的代碼中應該很少會用到,之所以需要partial,
是因為Metro
UI的介面是用XAML畫的,VS會把XAML傳變為實際代碼,因為這些UI代碼跟本身開發的UI邏輯代碼等是屬於同一個類,所以XAML轉變的那部分會
被定義為partial,然後編譯的時候會被自動合并。
好了,關於C++ /CX的特性就說這麼多,其實這些以外/CX還有很多新特性,比如內建類型,C++模板,枚舉,異常等方面都有一些新的擴充。還是那句話,本文只是個說明的引子,更全的資料參照MSDN吧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.