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

深入探索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>
            欧美91福利在线观看| 激情av一区| 一区二区三区不卡视频在线观看| 亚洲一区www| 在线午夜精品自拍| 亚洲一区三区视频在线观看| 亚洲综合第一| 久久久久国产免费免费| 久久色在线播放| 亚洲国产精品久久久| 女女同性女同一区二区三区91| 欧美成在线观看| 亚洲精品色图| 欧美亚洲综合网| 久久久久久久999| 欧美黄色一区| 国产精品夜夜夜| 在线观看视频日韩| 亚洲一区二区三区色| 免费在线观看成人av| 国产精品久久久久久av下载红粉| 国产欧美va欧美不卡在线| 亚洲国产成人av| 午夜精品视频网站| 牛牛国产精品| 亚洲一级特黄| 免费观看在线综合色| 国产九九视频一区二区三区| 亚洲日本中文字幕| 久久精品国产欧美亚洲人人爽| 亚洲国产成人av好男人在线观看| 亚洲视频大全| 欧美激情第一页xxx| 激情欧美一区二区三区在线观看| 亚洲一区国产精品| 亚洲国产老妈| 久久免费精品视频| 国产精品素人视频| 中日韩视频在线观看| 美日韩精品视频| 亚洲制服少妇| 欧美视频三区在线播放| 亚洲国产专区| 久久琪琪电影院| 亚洲综合精品四区| 国产精品久久久久久久免费软件| 亚洲激情偷拍| 久久影院午夜片一区| 午夜精品久久久久久久蜜桃app| 欧美日本高清一区| 亚洲品质自拍| 亚洲电影免费观看高清| 亚洲女与黑人做爰| 免费不卡中文字幕视频| 伊人久久亚洲美女图片| 国产自产精品| 性做久久久久久| 99视频精品免费观看| 欧美激情第4页| 99国产精品久久久久久久久久| 欧美激情aⅴ一区二区三区| 久久久久国产免费免费| 国产区精品视频| 久久精品免费看| 久久高清福利视频| 在线日韩av| 欧美激情视频一区二区三区免费| 久久综合伊人| 99re6热只有精品免费观看| 亚洲人成网在线播放| 欧美片在线观看| 亚洲综合首页| 午夜精品亚洲| 黄色成人在线| 亚洲国产黄色| 国产精品国产a| 亚洲伊人一本大道中文字幕| 国产精品视频九色porn| 性欧美长视频| 久久精品日韩| 91久久精品一区二区三区| 亚洲国产精品一区二区第一页| 欧美日韩另类视频| 欧美在线观看一区二区三区| 午夜精品久久久久久久99水蜜桃| 在线看不卡av| 久久久久久网站| 欧美激情区在线播放| 亚洲一区二区精品视频| 亚洲欧美中文在线视频| 在线观看一区欧美| 亚洲美女精品久久| 国产亚洲永久域名| 最新成人av网站| 国产精品亚洲综合色区韩国| 欧美成人精品三级在线观看| 欧美午夜激情在线| 久久综合精品国产一区二区三区| 欧美成人午夜| 午夜视频在线观看一区| 麻豆精品视频在线观看| 亚洲欧美国产一区二区三区| 久久―日本道色综合久久| 在线视频亚洲欧美| 久久天天躁狠狠躁夜夜爽蜜月| 在线视频欧美日韩精品| 久久av一区二区三区漫画| 日韩一区二区免费高清| 久久精品国产综合| 欧美亚洲系列| 欧美三级日本三级少妇99| 免费日韩精品中文字幕视频在线| 国产精品国产a级| 亚洲精品日韩在线观看| 亚洲国产婷婷| 久久不射中文字幕| 亚洲欧洲av一区二区| 欧美精品麻豆| 国产精品高潮粉嫩av| 国产精品一区二区黑丝| 亚洲精品美女久久久久| 在线观看亚洲精品| 午夜在线视频观看日韩17c| 亚洲一区日韩| 欧美日韩一区二区三区在线看 | 欧美精品性视频| 欧美chengren| 精东粉嫩av免费一区二区三区| 亚洲在线成人精品| 亚洲女同性videos| 欧美连裤袜在线视频| 亚洲电影视频在线| 亚洲国产另类久久久精品极度| 欧美中文字幕在线观看| 亚洲免费视频在线观看| 欧美视频日韩视频在线观看| 欧美视频在线观看免费| 中文在线一区| 欧美日韩伦理在线免费| 亚洲欧洲一区二区三区| 亚洲区在线播放| 欧美高清视频www夜色资源网| 欧美a级片一区| 亚洲精品自在在线观看| 免费日韩精品中文字幕视频在线| 蜜臀久久99精品久久久久久9| 欧美午夜精品久久久久久超碰| 亚洲伦伦在线| 在线亚洲欧美专区二区| 中文av字幕一区| 欧美国产综合| 一区二区欧美在线| 欧美日韩午夜剧场| 亚洲你懂的在线视频| 性欧美xxxx视频在线观看| 国产精品婷婷| 久久综合色婷婷| 日韩一区二区免费看| 午夜精品在线| 一区二区三区在线观看国产| 欧美成va人片在线观看| 夜夜爽99久久国产综合精品女不卡| 亚洲视频一二区| 国产午夜精品久久久久久免费视| 欧美影院视频| 亚洲国产视频直播| 一区二区三区视频观看| 国产美女精品| 久久一区亚洲| 亚洲午夜免费视频| 男女精品视频| 亚洲一级在线观看| 国产尤物精品| 欧美日韩高清在线观看| 午夜宅男欧美| 亚洲激情亚洲| 久久久久成人精品| 日韩视频精品| 国际精品欧美精品| 欧美噜噜久久久xxx| 香蕉久久国产| 亚洲人人精品| 久色成人在线| 午夜精品国产| 亚洲精品国产精品久久清纯直播| 欧美色图天堂网| 久久在线视频在线| 亚洲美女中文字幕| 久久综合图片| 亚洲欧美三级伦理| 亚洲美女中文字幕| 影音国产精品| 国产一区二区日韩精品欧美精品| 欧美片在线观看| 欧美成人一区二区三区| 欧美在线中文字幕| 亚洲午夜小视频| 亚洲精选在线观看| 亚洲国产合集| 亚洲国产福利在线|