<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      構(gòu)造函數(shù)產(chǎn)生的點(diǎn)及原因

      我相信很多人對構(gòu)造函數(shù)在什么時(shí)候產(chǎn)生,以及產(chǎn)生的原因,理解得不是很透徹;更有甚者認(rèn)為默認(rèn)構(gòu)造函數(shù)和復(fù)制構(gòu)造函數(shù)是一定會(huì)產(chǎn)生的,成員變量就應(yīng)該在初始化參數(shù)列表中進(jìn)行初始化,當(dāng)然這些是初學(xué)者的認(rèn)識(shí),下面分享一下我的看法。

      構(gòu)造函數(shù)不負(fù)責(zé)分配內(nèi)存,只是在分配好的一塊內(nèi)存中進(jìn)行賦值操作.這一點(diǎn)我們可以很容易從new/delete與malloc/free的區(qū)別中看出來,malloc/free只負(fù)責(zé)分配內(nèi)存不負(fù)責(zé)初始化,而new/delete不僅負(fù)責(zé)分配內(nèi)存,如果對象存在相應(yīng)的夠著函數(shù),就會(huì)調(diào)用相應(yīng)的構(gòu)造函數(shù),如果不存在當(dāng)然就不調(diào)用,如int *i=new int[10];int類型沒有構(gòu)造函數(shù),所以new只負(fù)責(zé)分配40字節(jié)的內(nèi)存,將首地址賦給i,沒有其他多于的操作,而string  *s=new string();不僅要分配string一個(gè)實(shí)例所需要的內(nèi)存,還要調(diào)用string的default constructor,說這么多我只想說,構(gòu)造函數(shù)不負(fù)責(zé)分配內(nèi)存,只負(fù)責(zé)初始化,也就是說一個(gè)實(shí)例你想不想初始化,怎么初始化那是你程序員的事,跟編譯器無關(guān),編譯器只在需要構(gòu)造函數(shù)的時(shí)候,才會(huì)合成相應(yīng)的構(gòu)造函數(shù),不需要的時(shí)候就不會(huì)合成。

      先看一個(gè)簡單的類:

      class Point
      
      {
      
      public:
      
             int x;
      
             int y;
      
      };

       

      執(zhí)行以下簡單的代碼:

      int main() {
      
             {  
      
                    Point *p=new Point;
      
                    cout<<p->x<<endl;//第4行
      
                    Point p1;
      
                    //cout<<p1.x;//第6行
      
                    p1.x=0;
      
                    p1.y=0;
      
                    Point p2(p1);//第9行
      
             }
      
              getchar();
      
           return 0;
      
      }

      第4行沒有任何問題,x是個(gè)隨機(jī)數(shù),第6行就報(bào)錯(cuò)了,說x沒有初始化,說明編譯器沒有自動(dòng)合成default constructor構(gòu)造函數(shù),隨機(jī)數(shù)就說明沒有初始化啊,難道編譯器會(huì)傻不啦嘰的給你初始化成一個(gè)隨機(jī)數(shù),你看看隨機(jī)函數(shù)的源碼,你知道人家有多努力的幫你隨機(jī)了,人家背地里默默地幫你做了很多事的,只能說明編譯器沒有幫你初始化,初始化工作就是程序員的事,至少C++是這樣,C#編譯器會(huì)幫你初始化。

      第9行也不會(huì)導(dǎo)致產(chǎn)生copy constructor,因?yàn)檫@個(gè)類簡單到實(shí)在沒有必要合成復(fù)制構(gòu)造函數(shù),編譯器完全可以在給p2分配完地址后,直接:Memcpy(&p2,&p1,sizeof(Point));不就是把一個(gè)地址的內(nèi)容直接拷貝到另一個(gè)地址中去嘛,不用通夠著函數(shù)的,構(gòu)造函數(shù)還得一個(gè)的給字段賦值,多慢,在對象很簡單的境況下,用memset進(jìn)行初始化,memcpy進(jìn)行賦值比給字段一個(gè)一個(gè)的賦值是要快一些的。說了這么多廢話,那夠著函數(shù)在什么情況下回產(chǎn)生呢?

      一句話:在逐位拷貝解決不了問題的情況下,就得合成構(gòu)造函數(shù)。說到這里其實(shí)大家差不多可以散了(只要你能深層次的理解這句話),但是我還有很多話要對你說。

      需要產(chǎn)生default constructor的情況

      1:成員變量含有default constructor

      2:父類中含有default constructor

      3:含有virtual function

      4:繼承關(guān)系中存在virtual繼承

      其實(shí)這4點(diǎn)概括一下就是兩點(diǎn):需要執(zhí)行default constructor和實(shí)例中存在指向方法表的指針。在這4種情況下,僅僅是分配所需要的內(nèi)存是不夠的,前兩種需要執(zhí)行相應(yīng)的default constructor,相應(yīng)的代碼當(dāng)然是放在當(dāng)前對象的默認(rèn)構(gòu)造函數(shù)中,后兩種情況是因?yàn)橹赶蚍椒ū淼闹羔樞枰跏蓟?,哥,這個(gè)必須初始化啊,是編譯器的職責(zé)啊,而字段是否初始化時(shí)程序員的職責(zé)。除了這4種情況,默認(rèn)構(gòu)造函數(shù)是不需要合成的,我都說了,構(gòu)造函數(shù)不負(fù)責(zé)分配內(nèi)存,編譯器也不負(fù)責(zé)初始化,在沒事的情況下編譯器是不會(huì)多事的,如果程序員多事的加上了相關(guān)的構(gòu)造函數(shù),那絕對是手賤,你的代碼很難快過編譯器。

       

      復(fù)制構(gòu)造函數(shù)也是在需要的時(shí)候才合成,不需要的時(shí)候就不會(huì)合成,還是那句話,在逐位拷貝解決不了問題的情況下,就會(huì)合成復(fù)制構(gòu)造函數(shù),在里面做一些力所能及的事。

      需要產(chǎn)生復(fù)制構(gòu)造函數(shù)的情況:

      1:成員變量含有copy constructor

      2:父類含有copy constructor

      3:含有virtual function

      4:繼承關(guān)系中含有虛繼承

      貌似產(chǎn)生的原因和default constructor差不多啊,還是要調(diào)用相應(yīng)的構(gòu)造函數(shù),給指向方法表的指針賦值。如將一個(gè)子類對象賦給父類對象,就需要修改方法表的指向,因?yàn)橹惡透割惖姆椒ū砜赡苁遣灰粯拥陌?,更多原因請看我?a href="http://www.rzrgm.cn/hlxs/p/3214062.html">虛方法的調(diào)用是怎么實(shí)現(xiàn)的(單繼承VS多繼承)

      構(gòu)造函數(shù)是不會(huì)有事沒事的產(chǎn)生的,不要再說那6個(gè)函數(shù)是一定會(huì)產(chǎn)生的了,只是在需要的時(shí)候才產(chǎn)生嗎,還有一點(diǎn)讓我受不了的就是關(guān)于初始化參數(shù)列表,瘋狂的迷信初始化參數(shù)列表,導(dǎo)致初始化參數(shù)列表很長,當(dāng)然用初始化參數(shù)列表是不會(huì)響應(yīng)性能啊,而且有的成員變量只能在初始化參數(shù)列表中初始化,但是有的成員變量在初始化參數(shù)列表中初始化和在構(gòu)造函數(shù)中初始化性能是一樣的。那干嘛要把初始化參數(shù)列表搞得那么長呢?看著就蛋疼。

      如果一個(gè)成員變量沒有默認(rèn)構(gòu)造構(gòu)造函數(shù),且也不需要合成默認(rèn)構(gòu)造函數(shù),且可以不再初始化參數(shù)列表中初始化,那么他在初始化參數(shù)列表中初始化和在構(gòu)造函數(shù)內(nèi)初始化是一樣的,原因很簡單,構(gòu)造函數(shù)不會(huì)針對這樣的成員變量合成多于的代碼,在哪里初始化都一樣,但是成員變量如果有相關(guān)構(gòu)造函數(shù),編譯器就會(huì)幫你調(diào)用,初始化參數(shù)列表中的代碼會(huì)放到構(gòu)造函數(shù)中,如果變量在初始化參數(shù)列表中初始化,就只初始化一次,而如果在夠著函數(shù)中初始化,編譯器看你沒有在初始化參數(shù)列表中初始化,以為你沒初始化,就產(chǎn)生代碼幫你初始化了,而你又在構(gòu)造函數(shù)中初始化那就初始化兩次了,這就是為什么很多初學(xué)者認(rèn)為初始化參數(shù)列表性能高的原因。

       

      綜上所述:在逐位拷貝解決不了問題時(shí),編譯器才合成相關(guān)的構(gòu)造函數(shù),執(zhí)行相關(guān)的代碼,在初始化的時(shí)候,看你沒有初始化,而又有相關(guān)的構(gòu)造函數(shù),于是就幫你調(diào)用了,其他情況編譯器概不負(fù)責(zé),那是我們程序員自己的事。

      posted @ 2013-08-25 16:41  古文觀芷  閱讀(2497)  評(píng)論(3)    收藏  舉報(bào)
      主站蜘蛛池模板: 免费午夜无码片在线观看影院| 亚洲欧美日韩综合久久久| 國产AV天堂| 久久精品蜜芽亚洲国产av| 自拍偷拍视频一区二区三区| 动漫AV纯肉无码AV电影网| 果冻传媒一区二区天美传媒| 免费无码又爽又刺激成人| 精品国产丝袜自在线拍国语| 太保市| 午夜一区欧美二区高清三区| 老师扒下内裤让我爽了一夜| 国产精品自在线拍国产手青青机版| 国产不卡一区二区在线视频| 成人亚洲av免费在线| 浦东新区| 国产免费又黄又爽又色毛| 亚洲欧美成人一区二区在线电影| 国产69精品久久久久99尤物| 日本三级理论久久人妻电影| 国产高清视频在线播放www色| 国产精品中文字幕自拍| 一级女性全黄久久生活片| 国产一级r片内射免费视频| 国产一区二区在线激情往| 亚洲色成人一区二区三区人人澡人人妻人人爽人人蜜桃麻豆 | 国产午夜福利视频在线| 福利在线视频一区二区| 人人做人人妻人人精| 无码伊人久久大杳蕉中文无码| 日本高清在线观看WWW色| 久播影院无码中文字幕| 4hu44四虎www在线影院麻豆 | 国产午夜精品久久精品电影| 日韩精品中文女同在线播放 | 国产精品 自在自线| 中文字幕无码av不卡一区| 国内揄拍国内精品对久久| 亚洲精品不卡av在线播放| 亚洲国产色婷婷久久99精品91| 午夜福利国产片在线视频|