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

深入探索C++對象模型讀書筆記 (二)

Posted on 2010-03-03 22:23 rikisand 閱讀(1402) 評論(4)  編輯 收藏 引用 所屬分類: C/C++

構造函數語義學

--了解編譯器在構造對象時背著我們干了什么勾當

Default Ctor 在需要的時候被構建出來~

什么需要? 是編譯器需要而不是程序的需要,所以不要期望編譯器生成的Ctor會幫我們把我們的成員變量初始化為零。那是程序的需要,也就是我們程序員的任務····

例如:

      class Foo(public:int val;);

      void foo_bar(){Foo bar; if(bar.val)dosth;} 不要期望編譯器幫我們初始化它為0。只有global變量會初始化為0,初始化val這樣的變量需要我們自己寫代碼的~~

Default Ctor分為trival(沒用的)和non-trival的,下面討論什么時候編譯器需要ctor 也就是有用的ctor,這時候如果我們沒有提供一個默認的default ctor 它會幫我們合成一個的~~

1.帶有Default Ctor 的member class object

很好理解,既然內部成員含有default ctor 那么我們創建新的對象時需要調用它,而我們并木有調用它的函數,編譯器自然會幫我們提供一個。如果我們提供了default ctor ,那么編譯器會在我們提供的函數加入調用必須調用的member class 的default ctor。同樣的在每一個ctor里面都將在用戶寫的代碼之前調用需要調用的default ctor -------看例子:

class Dopey();class Sneezy{public:Sneezy(int val);Sneezy();};class Bashful{public:BashFul();};

class Snow_white{public: Dopey dopey;Sneezy sneezy;Bashful bashful;private:int muble};

如果Snow_white沒有定義default ctor 那么編譯器會創建一個,并在其中依照聲明順序依次調用dopey sneezy bashful的default ctor 然而如果:

Snow_white::Snow_white():sneezy(1024){muble=2045;}

編譯器會擴張為

Snow_white::Snow_white():sneezy(1024){

  dopey.Dopey::Dopey();

  sneezy.Sneezy::Sneezy(1024);

  bashful.Bashful::Bashful();

  /////////   explicit user code

  muble = 2048;

}

2.派生自帶有Default ctor 的 base class

同樣道理如果父類有Default ctor 子類當然要調用,編譯器會為想上面一樣為我們加上

3.含有virtual functions的Class

創建object 時候需要ctor 來設置好vptr

4.帶有virtual base class

virtual base 實現方法各有不同,然而共同點是必須是virtual base class 在其每一個derived class中的位置能夠與執行期準備妥當

X A B C 菱形繼承

void foo(const A*pa){pa->i=1024;}

foo(new A);foo(new C);

知道pa 后 i在對象中的位置并不是固定的,而是在運行時真正確定pa指向什么對象A還是C才能確定的,因此需要設定一個指向基類subobject的指針,所以需要ctor工作了

OK:

1.任何class 如果沒有定義Default ctor 就會被合成一個

2.合成出來的Default ctor 會明確設定每一個data member值

錯的很easy了~

-------------------------------------------------------------------------------

再來看 Copy Ctor:

copy ctor 負責用另一個對象初始化一個對象

operator = 負責用另一個對象給一個對象賦值

直接賦值時,傳參時,返回時可能調用Copy ctor

Default member initialization~~~

也就是memberwise 的initialization

他會把每一個data member (內建的或者派生的)從一個object 拷貝到另一個object中去

如果object允許bitwise的拷貝那么編譯器就不用生成一個nontrival的default copy ctor

什么時候不可以呢~

1 內含一個member object 而后者含有copy constructor (聲明或者合成的)

2  繼承一個base class 后者有copy ctor

3  含有virtual func

4  派生自一個繼承鏈,其中有virtual base class

1和2 中編譯器會把member 或者baseclass copy ctor 調用安插在合成的copy ctor 中

3 中:

如果兩個同樣類型的object賦值時,沒有問題因為他們的vptr相同

但是考慮子類賦值給父類,此時vptr需要更改,那么此時不具有bitwise特性,因此需要編譯器來加入語句正確更新vptr

4中:

每個編譯器都承諾必須讓derived class 中的virtual base class object 在執行期間準備妥當,維護位置完整性是編譯器的責任。bitwise copy 有可能會破壞這個位置所以編譯器需要在自己合成的copy ctor 中作出仲裁

同樣問題發生在繼承體系中子類向父類賦值時,由于對象模型問題,直接bitwise復制可能會導致base class object 的破壞(后面章節會有討論)

--------------------------------------------------------------------------------

程序轉化語義學:

X x0;

void foo(){X x1(x0); X x2=x0; X x3=X(x0);}

轉化:重寫定義,初始化操作會被剝除   copy constructor 調用會被安插

void foo(){ X x1;X x2; X x3;  x1.X::X(x0); x2.X::X(x0); x3.X::X(x0);}

 

參數的初始化:

一種策略導入暫時的object

void foo(X x0);X xx; foo(xx);

轉化:

X _tmp;

_tmp.X::X(x0); foo(_tmp);

foo變成 void foo(X& x0);

另一種是拷貝構建:

把實際參數直接建構造應該在的位置上,函數返回時局部對象的destructor 會執行

也就是說把x0建構在foo 的函數執行的地方

 

返回值的初始化:

X bar(){

    X xx;

    return xx;

}

返回值如何從局部對象xx拷貝而來呢?

一種方法:1.加上額外參數,類型是class object的reference,這個參數用來放置被拷貝建構的返回值 (注意拷貝建構也就是說他被放在應該在的位置,也就是說不是局部變量了)

2.return 指令之前安插一個copy constructor 調用操作 ,以便將傳回的object 內容當做上述參數的初值

so 上面的程序變成了:

void bar(X& _result){

  X xx;

  xx.X::X(); //編譯器產生的default ctor 調用

  _result.X::X(xx);//編譯器產生的copy ctor 調用

  return ;

}

現在編譯器必須轉換bar的調用操作 X xx=bar();轉換成 X xx; bar(xx); // 注意不用copy ctor了直接操作在xx上了 如果編譯器做了優化 這就是named return value 優化

而:

bar.memfunc();//bar()傳回的X 調用成員函數

變成:

X _tmp;  (bar(_tmp),_tmp).memfunc();

同樣道理函數指針 X(*pf)(); 變成 void (*pf)(X&);

使用者的優化:

X bar(const T& y,const T& z){

    X xx;

    通過 y z 計算xx

   return xx;

}

這種情況下要iuxx被memberwise拷貝到編譯器產生的_result中,

如果定義 ctor來利用yz計算xx則:

X bar(const T& y,const T& z){

     return X(y,z);

}

變成:

bar(X& result){

     result . X::X(y,z);

     return;

}

無需copy ctor了

 

編譯器的優化:

如上所述bar中返回了具名數值 named value,因此編譯器有可能自己優化,方法是以result取代named return value

bar(X& result){_result.X::X(); 直接處理result 并不處理變量xx然后復制給result 這樣就優化了}

這個優化的激活需要class提供一個copy ctor~~~~~~

 

Copy ctor 要不要:

如果一個class 符合bitwise的要求那么此時member wise 的拷貝已經高效簡潔 無需加入了

但是如果class需要大量的member wise 初始化操作,如用傳值方式返回objects,如果是這樣提供一個copy ctor 可以激活nRV named return value 優化,這就很合理了

 

成員們的初始化過程:

什么時候必須用初始化列表:

1.初始化一個reference時 2.初始化一個const member 3.調用父類ctor而且有參數時4調用member class ctor 有參數

其他情況呢:

class word{string name;int cnt;public: name=0;cnt=0;}

編譯器可能這么做:

word::word{

    name.String::string();調用string的default ctor

    string tmp=string(0);

_name.string::operator=(tmp);

tmp.string::~string();

cnt=0;

}

顯然name放到初始化列表會更有效率 ,會變成

name.String::String(0);

而cnt這種內建類型則沒有關系,放不放到初始化列表沒有效率上的差別

初始化列表究竟讓編譯器做了什么????

編譯器會一個個操作list中的式子,以適當次序在ctor內安插初始化操作在任何explicit user code 之前。

注意的地方:

       list中的次序是按照members聲明次序決定而不是list 中的排列順序決定。

例如:class x{int i;int j; X(int val):j(val),i(j)}

錯了 i先聲明則i首先賦予val 然后用未初始化的j賦給i。。。

可以這樣X::X(int val):j(val){i=j;}

由于會安插在explicit code 之前 所以沒問題 會變成 j=val;   i=j;

可否用member functions 初始化成員??

答案是可以的,因為和objects相關的this指針已經構建妥當,只是要注意函數調用的member是否已經構建妥當了即可

------         -  -  - ----------       --       --疲憊的結束線-          - -  -     - --            -           -----

name return value TEST:

~~~~1 cl /od 不開優化

#include <iostream>
using namespace std;
class RVO
{
public:

    RVO(){printf("I am in constructor\n");}
    RVO (const RVO& c_RVO) {printf ("I am in copy constructor\n");}
    ~RVO(){printf ("I am in destructor\n");}
    int mem_var;      
};
RVO MyMethod (int i)
{
    RVO rvo1;
    rvo1.mem_var = i;
    return (rvo1);
}
int main()
{
    RVO rvo;rvo=MyMethod(5);
}

輸出:

I am in constructor         //rvo 創建
I am in constructor         // rvo1創建
I am in copy constructor // rvo1賦值給hiddern
I am in destructor          // rvo1解構
I am in destructor          // hiddern解構
I am in destructor         //  rvo 解構

A MyMethod (A &_hiddenArg, B &var)
{
   A retVal;
   retVal.A::A(); // constructor for retVal
   retVal.member = var.value + bar(var);
   _hiddenArg.A::A(retVal);  // the copy constructor for A
   return;
retVal.A::~A();  // destructor for retVal

}
A MyMethod(A &_hiddenArg, B &var)
{
   _hiddenArg.A::A();
   _hiddenArg.member = var.value + bar(var);
   Return
}
~~~~2 cl /o2 代碼同上
output

I am in constructor  //rvo創建
I am in constructor  //hiddern 創建
I am in destructor   //hiddern 解構
I am in destructor   //rvo解構

我不明白的是hiddern 怎么傳給rvo ,我猜可能是編譯器按照bitwise的復制方式進行的,此時編譯器并沒有直接建構結果于rvo上 ,看看下面的試驗:

注:明白了, 結果直接建構在hiddern,然后通過operator = 傳給rvo 。沒有copy ctor因為拷貝構造函數是負責初始化的,而operator = 才是用來賦值的.

經過代碼證明是對的,如果重載賦值運算符 輸出變成:

I am in constructor  //rvo創建
I am in constructor  //hiddern 創建

I am in operator =   //賦值操作~~
I am in destructor   //hiddern 解構
I am in destructor   //rvo解構

~~~~3 cl /od

#include <iostream>
using namespace std;
class RVO
{
public:

    RVO(){printf("I am in constructor\n");}
    RVO (const RVO& c_RVO) {printf ("I am in copy constructor\n");}
    ~RVO(){printf ("I am in destructor\n");}
    int mem_var;      
};
RVO MyMethod (int i)
{
    RVO rvo1;
    rvo1.mem_var = i;
    return (rvo1);
}
void abc(RVO& i){
}
int main()
{
    RVO rvo=MyMethod(5);  //此時定義和賦值放到了一個表達式子
    return 0;
}

output:

I am in constructor           // rvo1 創建 注意 跟上面的第一種情況下的hiddern一樣 rvo并沒有調用ctor
I am in copy constructor   // rvo1 拷貝構造給rvo 此時沒有hiddern了 直接構建rvo了
I am in destructor            // rvo1 析構
I am in destructor            // rvo1 解構

~~~~3 cl /o2  再來~~~~ NRV出馬

I am in constructor           // rvo構建了 
I am in destructor            // rvo析構了

此時 mymethod中的一切都直接反映在rvo身上

ok~~~~~4個代碼完全一樣構造析構拷貝函數個數由2-6不等~~~over~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Feedback

# re: 深入探索C++對象模型讀書筆記 (二)  回復  更多評論   

2010-03-11 09:13 by zmm
不錯,很基礎的

# re: 深入探索C++對象模型讀書筆記 (二)  回復  更多評論   

2010-03-11 13:56 by zmm
~~~~3 cl /o2 再來~~~~ NRV出馬

I am in constructor // rvo構建了
I am in copy constructor // rvo析構了

這里打錯了吧,是in destructor吧~

# re: 深入探索C++對象模型讀書筆記 (二)  回復  更多評論   

2010-03-11 14:01 by rikisand
恩 ~~ 改過來啦 你看的好仔細啊~~

# re: 深入探索C++對象模型讀書筆記 (二)  回復  更多評論   

2010-03-11 16:32 by zmm
@rikisand
呵呵,因為沒有看到destroy,所以我運行了一下~
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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久久久久久久vr| 久久精品视频在线看| 久久精品二区三区| 99re热这里只有精品视频| 欧美大片免费观看| 亚洲福利在线观看| 在线精品视频一区二区三四| 国产日韩欧美91| 激情久久影院| 在线观看国产精品淫| 亚洲国产精品电影在线观看| 艳妇臀荡乳欲伦亚洲一区| 亚洲视频日本| 久久国产精品久久久久久电车| 久久av一区二区三区漫画| 久久久www成人免费毛片麻豆| 美女久久一区| 99香蕉国产精品偷在线观看| 亚洲欧美亚洲| 久久亚洲精品伦理| 欧美新色视频| 亚洲成人资源| 亚洲自拍偷拍麻豆| 欧美不卡福利| 99国产精品视频免费观看| 亚洲综合视频一区| 久久亚裔精品欧美| 欧美亚一区二区| 亚洲成人直播| 国产精品久久久久久久免费软件 | 欧美激情区在线播放| 国产精品v日韩精品| 久久婷婷av| 亚洲精品色婷婷福利天堂| 亚洲资源在线观看| 欧美电影免费| 国产一区二区精品久久91| 日韩视频免费观看| 久久亚洲一区二区| 亚洲午夜高清视频| 欧美激情中文字幕乱码免费| 国产综合色精品一区二区三区| 一二三四社区欧美黄| 欧美成人一区二区三区片免费| 在线视频精品一| 免费久久久一本精品久久区| 国产精品观看| 一区二区三区四区国产| 欧美成人黑人xx视频免费观看| 在线亚洲国产精品网站| 另类国产ts人妖高潮视频| 国产一二三精品| 亚洲激情婷婷| 亚洲丰满少妇videoshd| 久久亚洲精品网站| …久久精品99久久香蕉国产 | 国产精品一区二区久久久| 91久久夜色精品国产九色| 久久综合九色| 久久久人成影片一区二区三区| 国产一区二区三区成人欧美日韩在线观看 | 国产手机视频一区二区| 午夜一级在线看亚洲| 99av国产精品欲麻豆| 欧美极品在线观看| 亚洲欧洲一级| 亚洲毛片播放| 欧美日本一区二区视频在线观看 | 久久国产精品久久久久久| 亚洲一区美女视频在线观看免费| 欧美精品一区二区三区很污很色的| 亚洲精品1区2区| 亚洲成在线观看| 欧美激情亚洲一区| 宅男噜噜噜66一区二区| 中文精品视频| 国产一区二区三区网站| 免费人成精品欧美精品| 欧美成人免费观看| 亚洲午夜久久久久久久久电影院 | 欧美福利在线观看| 亚洲欧洲视频| av成人免费观看| 国产精品久在线观看| 国产精品成人观看视频免费 | 欧美日韩午夜剧场| 亚洲综合日韩在线| 日韩天堂在线观看| 国产婷婷97碰碰久久人人蜜臀| 欧美在线国产| 免费观看成人| 亚洲日韩第九十九页| 亚洲视频一区二区| 国产精品伦一区| 久久久精品欧美丰满| 久久精品伊人| 亚洲人成7777| 亚洲欧美伊人| 亚洲电影av在线| 亚洲已满18点击进入久久| 国产在线精品二区| 久久成人精品无人区| 亚洲视频大全| 亚洲欧美日韩国产一区二区| 亚洲国产精品电影在线观看| 亚洲日本中文字幕免费在线不卡| 国产精品无人区| 毛片av中文字幕一区二区| 国产精品分类| 欧美a级片一区| 国产精品国产三级国产aⅴ浪潮| 欧美在线视频免费观看| 欧美人妖另类| 久久香蕉精品| 国产欧美亚洲一区| 欧美大片一区二区| 国产一区二区三区免费在线观看| 欧美77777| 红桃视频一区| 欧美韩日亚洲| 在线日本高清免费不卡| 一区二区欧美精品| 亚洲日韩欧美视频| 午夜精品一区二区三区在线视| 一卡二卡3卡四卡高清精品视频 | 美女主播一区| 欧美一区午夜视频在线观看| 欧美日韩免费在线视频| 玖玖国产精品视频| 国模大胆一区二区三区| 一本大道久久a久久精品综合| 国产日韩欧美在线看| 日韩一级大片| 国产欧美一区二区精品仙草咪| 一区二区三区高清在线观看| 91久久久久久久久| 欧美a级在线| 久热爱精品视频线路一| 狠狠网亚洲精品| 亚洲欧美日韩在线高清直播| 午夜视频久久久| 欧美日韩ab片| 一级日韩一区在线观看| 日韩午夜av| 欧美午夜精品久久久| 亚洲精品极品| 亚洲免费视频在线观看| 欧美日产国产成人免费图片| 亚洲精品一二三区| 亚洲欧洲在线播放| 欧美精品三级日韩久久| 欧美激情精品久久久六区热门 | 蜜臀av国产精品久久久久| 亚洲第一区在线观看| 久久精品国产亚洲一区二区三区| 久久午夜精品| 极品尤物av久久免费看| 你懂的国产精品永久在线| 亚洲大胆美女视频| 日韩亚洲综合在线| 欧美破处大片在线视频| 亚洲一区二区高清| 日韩午夜在线电影| 国产精品卡一卡二| 在线视频精品一区| 亚洲大胆女人| 亚洲黄色性网站| 欧美视频一区二区三区在线观看 | 亚洲电影激情视频网站| 一区二区三区精密机械公司| 午夜在线视频观看日韩17c| 亚洲视频综合在线| 国产精品美女主播在线观看纯欲| 欧美国产精品久久| aa成人免费视频| 国产精品免费观看视频| 久久国产视频网站| 亚洲高清视频中文字幕| 在线高清一区| 欧美三级视频| 麻豆9191精品国产| 亚洲精品一区二区在线观看| 久久久一区二区三区| 亚洲日本成人在线观看| 国产区二精品视| 欧美成人午夜| 亚洲欧美大片| av成人动漫| 国产亚洲美州欧州综合国| 欧美成va人片在线观看| 亚洲网站在线看| 亚洲另类自拍| 久久亚洲私人国产精品va| 亚洲综合丁香| 国产欧美在线观看| 麻豆成人在线| 亚洲精品久久久久| 国产亚洲一级| 欧美性猛交xxxx免费看久久久|