乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      類的初始化和賦值

       @IT小小鳥@ 2012-03-07
      CSomeClass::CSomeClass()
      {
          x=0;
          y=1;
      }
      而在別的什么地方則寫成下面的樣子:
      CSomeClass::CSomeClass() : x(0), y(1)
      {
      }
      我的一些程序員朋友說第二種方法比較好,但他們都不知道為什么是這樣。你能告訴我這兩種類成員初始化方法的區(qū)別嗎?
      回答
      從技術上說,你的程序員朋友是對的,但是在大多數(shù)情況下,兩者實際上沒有區(qū)別。有兩個原因使得我們選擇第二種語法,它被稱為成員初始化列表:一個原因是必須的,另一個只是出于效率考慮。
      讓我們先看一下第一個原因——必要性。設想你有一個類成員,它本身是一個類或者結構,而且只有一個帶一個參數(shù)的構造函數(shù)。
      class CMember {
      public:
          CMember(int x) { ... }
      };
      因為Cmember有一個顯式聲明的構造函數(shù),編譯器不產(chǎn)生一個缺省構造函數(shù)(不帶參數(shù)),所以沒有一個整數(shù)就無法創(chuàng)建Cmember的一個實例。
      CMember* pm = new CMember;        // Error!!
      CMember* pm = new CMember(2);     // OK
      如果Cmember是另一個類的成員,你怎樣初始化它呢?你必須使用成員初始化列表。
      class CMyClass {
          CMember m_member;
      public:
          CMyClass();
      };
      //必須使用成員初始化列表
      CMyClass::CMyClass() : m_member(2)
      {
      }
      沒有其它辦法將參數(shù)傳遞給m_member,如果成員是一個常量對象或者引用也是一樣。根據(jù)C++的規(guī)則,常量對象和引用不能被賦值,它們只能被初始化。
      第二個原因是出于效率考慮,當成員類具有一個缺省的構造函數(shù)和一個賦值操作符時。MFC的Cstring提供了一個完美的例子。假定你有一個類CmyClass具有一個Cstring類型的成員m_str,你想把它初始化為"yada yada."。你有兩種選擇:
      CMyClass::CMyClass() {
          // 使用賦值操作符
          // CString::operator=(LPCTSTR);
          m_str = _T("yada yada");
      }
      //使用類成員列表
      // and constructor CString::CString(LPCTSTR)
      CMyClass::CMyClass() : m_str(_T("yada yada"))
      {
      }
      在它們之間有什么不同嗎?是的。編譯器總是確保所有成員對象在構造函數(shù)體執(zhí)行之前初始化,因此在第一個例子中編譯的代碼將調用CString::Cstring來初始化m_str,這在控制到達賦值語句前完成。在第二個例子中編譯器產(chǎn)生一個對CString:: CString(LPCTSTR)的調用并將"yada yada"傳遞給這個函數(shù)。結果是在第一個例子中調用了兩個Cstring函數(shù)(構造函數(shù)和賦值操作符),而在第二個例子中只調用了一個函數(shù)。在Cstring的例子里這是無所謂的,因為缺省構造函數(shù)是內聯(lián)的,Cstring只是在需要時為字符串分配內存(即,當你實際賦值時)。但是,一般而言,重復的函數(shù)調用是浪費資源的,尤其是當構造函數(shù)和賦值操作符分配內存的時候。在一些大的類里面,你可能擁有一個構造函數(shù)和一個賦值操作符都要調用同一個負責分配大量內存空間的Init函數(shù)。在這種情況下,你必須使用初始化列表,以避免不要的分配兩次內存。在內部類型如ints或者longs或者其它沒有構造函數(shù)的類型下,在初始化列表和在構造函數(shù)體內賦值這兩種方法沒有性能上的差別。不管用那一種方法,都只會有一次賦值發(fā)生。有些程序員說你應該總是用初始化列表以保持良好習慣,但我從沒有發(fā)現(xiàn)根據(jù)需要在這兩種方法之間轉換有什么困難。在編程風格上,我傾向于在主體中使用賦值,因為有更多的空間用來格式化和添加注釋,你可以寫出這樣的語句:x=y=z=0;
      或者memset(this,0,sizeof(this));
      注意第二個片斷絕對是非面向對象的。
      當我考慮初始化列表的問題時,有一個奇怪的特性我應該警告你,它是關于C++初始化類成員的,它們是按照聲明的順序初始化的,而不是按照出現(xiàn)在初始化列表中的順序。
      class CMyClass {
          CMyClass(int x, int y);
          int m_x;
          int m_y;
      };
      CMyClass::CMyClass(int i) : m_y(i), m_x(m_y)
      {
      }
      你可能以為上面的代碼將會首先做m_y=I,然后做m_x=m_y,最后它們有相同的值。但是編譯器先初始化m_x,然后是m_y,,因為它們是按這樣的順序聲明的。結果是m_x將有一個不可預測的值。我的例子設計來說明這一點,然而這種bug會更加自然的出現(xiàn)。有兩種方法避免它,一個是總是按照你希望它們被初始化的順序聲明成員,第二個是,如果你決定使用初始化列表,總是按照它們聲明的順序羅列這些成員。這將有助于消除混淆。

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多