• <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>

            Benjamin

            靜以修身,儉以養(yǎng)德,非澹薄無以明志,非寧靜無以致遠(yuǎn)。
            隨筆 - 397, 文章 - 0, 評(píng)論 - 196, 引用 - 0
            數(shù)據(jù)加載中……

            C++之構(gòu)造函數(shù)(Constructors)和static

            構(gòu)造函數(shù)和靜態(tài)成員:必須顯式定義靜態(tài)成員變量,不能出現(xiàn)在構(gòu)造的初始化列表中
            1  class Fred {
            2  public:
            3    Fred();
            4    
            5  private:
            6    int i_;
            7    static int j_;
            8  }; 
            Fred::Fred()
               : i_(
            10)  // OK: you can (and should) initialize member data this way
               , j_(42)  // Error: you cannot initialize static member data like this
             {
               
             }
             
             
            // You must define static data members this way:
             int Fred::j_ = 42
            通常把靜態(tài)成員的聲明放到.H文件,定義放到.cpp中。如果沒有定義,會(huì)出現(xiàn) "undefined external" 的鏈接錯(cuò)誤。
            靜態(tài)變量初始化順序產(chǎn)生的錯(cuò)誤是難以覺察,因?yàn)樗l(fā)生在mian之前,如果你有兩個(gè)靜態(tài)成員x,y,分別位于兩個(gè)文件x.cpp、y.cpp中,而y在初始化要調(diào)用x,這樣的場(chǎng)景很常見,出錯(cuò)的幾率有百分之五十。如果先初始化x,一切OK,如果先初始化y,那就慘了。例如:
            1  // File x.cpp
            2  #include "Fred.h"
            3  Fred x; 
            4 
            1 // File y.cpp
            2  #include "Barney.h"
            3  Barney y; 
            1  // File Barney.cpp
            2  #include "Barney.h"
            3  
            4  Barney::Barney()
            5  {
            6    
            7    x.goBowling();
            8    
            9  } 
            解決這種靜態(tài)成員初始化的方法很多,一個(gè)簡(jiǎn)單的方法就是用靜態(tài)方法x()替代Fred x,然后返回這個(gè)Fred的引用,如下所示:
            1  // File x.cpp
            2  
            3  #include "Fred.h"
            4  
            5  Fred& x()
            6  {
            7    static Fred* ans = new Fred();
            8    return *ans;
            9  } 
            這個(gè)靜態(tài)變量這初始化一次,以后將一直返回同樣的Fred對(duì)象。這是修改后的代碼
            1  // File Barney.cpp
            2  #include "Barney.h"
            3  
            4  Barney::Barney()
            5  {
            6    
            7    x().goBowling();
            8    
            9  } 
            第一次使用,F(xiàn)red對(duì)象先被構(gòu)造。但是這個(gè)解決方法使用時(shí)要慎重,在這里第一選擇是使用靜態(tài)成員,使用靜態(tài)指針會(huì)有一些副作用,倒不是擔(dān)心內(nèi)存泄露,在程序退出時(shí)系統(tǒng)會(huì)自己釋放這些堆空間。在使用靜態(tài)變量時(shí)要保證第一次使用前被初始化,最后一次使用后被析構(gòu),在這里我們要注意的是析構(gòu)函數(shù)的代碼。如果靜態(tài)變量a、b、c在構(gòu)造時(shí)調(diào)用ans沒問題,但是在析構(gòu)時(shí)如果還調(diào)用ans,程序極有可能崩潰。這種應(yīng)用在實(shí)際中并不多見,解決的方法有三種,待以后的主題中在講。
            在這里有個(gè)static initialization和static deinitialization,前者意義大家都知道,后者則是去初始化指的是在應(yīng)用之前被別的代碼給析構(gòu)了,導(dǎo)致我們用的這個(gè)靜態(tài)量沒有初始化,這個(gè)是很致命的,尤其在靜態(tài)指針中,表現(xiàn)的更為明顯。
            當(dāng)然static這個(gè)關(guān)鍵字也并非一無是處,下面的代碼中的錯(cuò)誤就可以用staic來解決:
             1 #include <iostream>
             2  
             3  int f();  // forward declaration
             4  int g();  // forward declaration
             5  
             6  int x = f();
             7  int y = g();
             8  
             9  int f()
            10  {
            11    std::cout << "using 'y' (which is " << y << ")\n";
            12    return 3*+ 7;
            13  }
            14  
            15  int g()
            16  {
            17    std::cout << "initializing 'y'\n";
            18    return 5;
            19  } 
            這段代碼顯然不能通過編譯,下面通過static改變了初始化的順序
             1 #include <iostream>
             2  
             3  int f();  // forward declaration
             4  int g();  // forward declaration
             5  
             6  int x = f();
             7  int y = g();
             8  
             9  int f()
            10  {
            11    std::cout << "using 'y' (which is " << y << ")\n";
            12    return 3*+ 7;
            13  }
            14  
            15  int g()
            16  {
            17    std::cout << "initializing 'y'\n";
            18    return 5;
            19  }
             1 #include <iostream>
             2  
             3  int f();  // forward declaration
             4  int g();  // forward declaration
             5  
             6  int x = f();
             7  int y = g();
             8  
             9  int f()
            10  {
            11    std::cout << "using 'y' (which is " << y << ")\n";
            12    return 3*+ 7;
            13  }
            14  
            15  int g()
            16  {
            17    std::cout << "initializing 'y'\n";
            18    return 5;
            19  } 

            但是上面的更改只限于編譯器的內(nèi)置數(shù)據(jù)類型,而不是用戶自定義的數(shù)據(jù)類型。

            posted on 2010-05-08 22:27 Benjamin 閱讀(1491) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++

            久久99精品久久久久久噜噜| 久久精品成人免费看| 久久亚洲色一区二区三区| 国产69精品久久久久APP下载| 亚洲AV日韩AV永久无码久久| 精品国产91久久久久久久a| 国产精品日韩欧美久久综合| 欧美一区二区三区久久综| 久久人人爽人人爽人人片AV麻豆 | 国内精品久久国产大陆| 国产成人综合久久精品尤物| 欧美一级久久久久久久大片| 久久综合狠狠综合久久激情 | 一本一本久久a久久综合精品蜜桃| 久久久久综合国产欧美一区二区| 中文字幕精品久久| 日本WV一本一道久久香蕉| 人妻精品久久无码区| 久久久久久久亚洲精品| 久久97久久97精品免视看| 色偷偷88888欧美精品久久久| 精品欧美一区二区三区久久久 | 精品国产VA久久久久久久冰| 国产精品久久久久蜜芽| 久久99热国产这有精品| 久久99热只有频精品8| 国产免费久久精品99re丫y| 日本精品久久久中文字幕| 狠狠狠色丁香婷婷综合久久五月| 婷婷国产天堂久久综合五月| 久久亚洲AV无码精品色午夜| 久久久久国产精品麻豆AR影院| 国产精品美女久久久久久2018| 青青草原综合久久大伊人| 久久国产成人午夜AV影院| 久久精品国产一区| 久久综合狠狠综合久久综合88| 囯产精品久久久久久久久蜜桃| 亚洲国产成人久久综合野外| 久久久久亚洲精品无码网址| 99久久无码一区人妻|