日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

《深度探索C++对象模型》--2 构造函数语意学

發布時間:2025/3/21 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《深度探索C++对象模型》--2 构造函数语意学 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1default constructor的構造操作

??C++standard:對于class X,如果沒有任何user-declared constructor,那么會有一個default constructor 被暗中(implicitly)聲明出來,一個被暗中聲明出來的default constructor將是一個trivial constructor但是這個生成的defaultconstructor只能滿足編譯器的需要,而不是程序的需要,所有的nonstaticdata member都不會被初始化,要注意。

??一個nontrivialdefault constructorARM的術語中就是編譯器所需要的那種,必要的話會由編譯器合成出來。下面討論nontrivial defaultconstructor的四種情況。

1)帶有defaultconstructormemberclass object如果一個類沒有任何constructor,但它內含一個memberobject,而后者有defaultconstructor,那么這個classimplicitdefault constructor就是”nontrivial“的。

??既然編譯器會合成默認構造函數,那么在C++各個不同的編譯模塊中,編譯器如何避免合成出多個默認構造函數(比如一個是a.c文件,另一個是b.c文件)呢?解決辦法是吧合成的default constructorcopyconstructordestructorassignmentcopy operator都以inline方式完成,一個inline函數有靜態鏈接,不會被文件以外看到。如果函數太復雜,不適合做成inline,就會合成出一個explicitnon-inline static實體。

?如果class內含一個以上的memberclass objects,那么此class的每一個constructor必須調用每一個memberclassdefaultconstructor。編譯器會擴張已經存在的constructor,在其中安插一些代碼,似的user code被執行之前,先調用必要的defaultconstructor,且以聲明順序調用。

2)帶有DefaultConstructorBaseClass如果一個沒有任何constructorclass派生自一個帶有defaultconstructorbase class,那么這個derivedclassdefaultconstructor會被視為nontrivial,并因此需要被合成出來。

3)帶有一個VirtualFunctionClass兩種情況

a)class聲明(或繼承)一個virtual function

?(b) class派生自一個繼承串鏈,其中有一個或更多的virtual base classes

有兩個擴張會在編譯期間發生:一個virtualfunction table會被編譯器產生出來,內放classvirtualfunctions地址;在每一個classobject中,一個額外的pointer member會被編譯器合成出來,內含相關的class vtbl的地址。

4)帶有一個VIrtualBase ClassClass: VirtualBase Class的實現法在不同的編譯器之間有極大差異,然而,每一種實現法必須使virtualbase class在每一個derivedclass object中的位置,能夠于執行期準備妥當。

2Copy Constructor的構建操作

1)當classobject以相同class的另一個object作為初值時,其內部是以所謂的default memberwise(按成員)initialization手法完成的。

2)如果class沒有聲明一個copyconstructor,就會有隱含的聲明或隱含的定義出現,C++standardcopyconstructor區分為trivialnontrivial兩種,只有nontrivial的實體才會被合成于程序之中。決定一個copy constructor是否為trivial的標準在于class是否展現出所謂的”bitwisecopy semantics“

3BitwiseCopy Semantics(逐位拷貝)

不要BitwiseCopy Semantics的情況有四種:

?a)當class內含一個memberobject而后者的class聲明有一個copyconstructor時(不論是被class設計者明確地聲明,還是被編譯器合成);

?b)當class繼承自一個baseclass而后者存在一個copyconstructor時(不論是被明確聲明還是被合成而得);

?c)當class聲明了一個或多個virtualfunctions時;

?d)當class派生自一個繼承串鏈,其中有一個或多個virtual base class時。

前兩種情況,編譯器需將memberbaseclasscopyconstructor調用操作安插到被合成的copyconstructor中,情況34有點復雜。

重新設定VirtualTable的指針:增加一個virtualfunction tablevtbl),內含每一個有作用的virtual function地址;將一個指向vtbl的指針(vptr),安插在每一個classobject內。

處理VirtualBase Class Subobject一個classobject以另一個object作為初值,而后者有一個virtual base class subobject,也會使bitwisecopy semantics失效。

3、程序轉化語意學

1)返回值的初始化

已知函數定義:

X bar()

{

X xx

//...

return xx;

}

bar()返回值如何從局部對象拷貝?

Stroustrupcfront的解決方法是一個雙階段轉化:

????加上一個額外參數,類型是reference

????return前安插一個copy constructor操作

//函數轉化

void bar(X& _result)//加上一個額外參數

{

X xx;

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

//....處理xx

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

return;

}

一個bar()調用被轉化為:

X xx = bar();

轉為:

X xx

barxx);//注意不必調用default constructor

2在編譯器層面做優化

_result參數取代namedreturn value,稱為NamedReturn ValueNRV)優化。由于NRV需要調用默認拷貝構造,如果編譯器不生成,則需要手動添加拷貝構造。

3)拷貝構造要還是不要?

如果class需要大量的memberwise初始化操作,例如以傳值的方式傳回value,則提供一個explicit copy constructor inline會更有效率。

4、成員的初始化隊伍

必須使用member initialization list的情況:初始化一個reference member時;初始化const member;調用base classconstructor,而它擁有一組參數;調用member classconstructor,而它擁有一組參數。

使用成員初始化列表,可以提高效率,因為initializationlist的項目被放于explicituser code之前,但是要注意如果初始化某一項依賴于另一項時初始化的順序,好的方法是將依賴某一項的成員放于constructor體內。




總結

以上是生活随笔為你收集整理的《深度探索C++对象模型》--2 构造函数语意学的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。