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

巢穴

about:blank

[轉]《深度探索C++對象模型》讀書筆記[二]

2002-7-6

3.3 Data Member的存取
1.   不管什么情況,每一個static data member只有一個實體,放在程序的data segment之中,每次程序取用static member,不管是通過operator::還是member selection operator,都會被內部轉化為對該唯一extern實體的直接參考操作。每一個static member的存取以及與class的關聯不會導致任何執行時間或空間上的額外負擔。如果有兩個classes,每一個都聲明了一個static member freeList,那么當它們都放在程序的data segment時,就會導致名稱沖突,編譯器的解決方法是使用name-mangling,暗中對每一個static data member編碼,以獲得一個獨一無二的程序識別代碼。

2.   有多少個編譯器,就有多少種name-mangling做法,任何name-mangling做法都有兩個要點:

ü          一種算法,推導出獨一無二的名稱;

ü          如果編譯系統或者環境工具必須和使用者交談,那些獨一無二的名稱可被輕易推導回原先的名稱。

3.   取一個static data member的地址,會得到一個指向其數據類型的常量指針,而不是指向其class member的指針。

4.   nonstatic data members直接放在每一個class object之中,除非經過顯示的explicit或隱含的implicit class object,沒有辦法直接存取它們。只要程序員在一個member function中直接處理一個nonstatic data member,所謂implicit class object就會發生,其實質是編譯器會為這個member function增添一個const this指針,而在函數體內通過這個this指針來存取nontatic data member。

5.   欲對一個nonstatic data member進行存取操作,編譯器需要把class object的起始地址加上data member的編譯量offset,如地址&someObject.someMember等于&someobject + (&theClass::someMember – 1);指向data member的指針,其offset值總是會被加上1,這樣可以使編譯系統區分出一個指向class第一個data member的指針和一個沒有指向任何data member的指針。

6.   每一個nonstatic data member的偏移量在編譯時期即可獲知,甚至如果member屬于一個單一或多重繼承體系中base class subobject也是一樣,因此其存取效率和一個C struct member或一個nonderived class的member的存取效率是一樣的。但是在虛擬繼承的情況下就另當別論了:如果該nonstatic data member是一個virtual base class的member,并且通過指針來存取的話,在編譯時期就不會得知這個member真正的offset位置,所以這個存取操作必須延遲至執行期,經由一個額外的間接導引才能夠解決。

2002-7-7

3.4 “繼承”與Data Member
1.   在C++繼承模型中,一個derived class object所表現出來的東西,是其自己的members加上其base classes members的總和。C++并未規定derived class members和base classes members的排列次序。不過,在大部分編譯器上,除virtual base class外,base class members總是先出現。

2.   一般而言,具體繼承concrete inheritance并不會增加空間或存取時間上的額外負擔。

3.   把兩個原本獨立不相干的classes湊成一對type/subtype,并帶有繼承關系容易犯兩個錯誤。一是可能會重復設計一些相同操作的函數,一般而言,選擇某些函數做成inline函數,是設計class的一個重要課題;二是把一個class分解為多層,有可能會為了表現class體系之抽象化,因為編譯器的邊界調整而膨脹所需空間。其根本原因是C++保證出現在derived class中的base class subobject有其完整原樣性。

4.   C++最初問世時,許多編譯器把vptr放在class object的尾端,這樣可以保留base class C struct的對象布局。此后,某些編譯器開始把vptr放在class object的開始處,這樣會給多重繼承下通過指向class members之指針調用virtual function帶來一些幫助,否則,在執行期不僅必須備妥從class object起點處開始量起的offset,而且必須備妥class vptr之間的offset。

5.   單一繼承提供了一種自然多態的形態,是關于class體系中base type和derived type之間的轉換。一般來說,base class和derived class objects都是從相同的地址開始。但若將vptr放在class object的起始處,如果base class沒有virtual function而derived class有,那么單一繼承的自然多態就會打破。此時,把一個derived object轉換為其base類型就需要編譯器的介入,用以調整地址。而在既是多重繼承又是虛擬繼承的情況下,編譯器的介入則更有必要。

6.   多重繼承的復雜度在于derived class和其上一個base class乃至上上一個base class之間的非自然關系,其主要問題發生在derived class objects和其第二或后繼的base class objects之間的轉換。對一個多重派生對象,將其地址指定給最左端base class的指針,情況將和單一繼承相同,而第二個或后繼的base class的地址指定操作則需要修改地址,加上或減去(若是downcast)介于中間的base class subobjects的大小。C++并未要求多重繼承時derived class object中各個base class subjectes的排列次序,目前各個編譯器都是根據聲明次序來排列它們。

7.   class內如果內含一個或多個virtual bass class subobjects,將被分割為兩部分:一個不變局部和一個共享局部。不變局部總是擁有固定的offset,其數據用以指定共享局部的位置,可以直接存取;而共享局部表現的就是virtual base class subobject,其位置會因為每次的派生操作而變化,只可間接存取。各家編譯器實現技術之間的差異就在于間接存取的方法不同。

8.   一般而言,virtual base class最有效的一種運用方式是:一個沒有任何data member的抽象class。

2002-7-14

3.5 對象成員的效率
如果沒有把優化開關打開,就很難猜測一個程序的效率表現,因為程序代碼潛在性的受到某些與編譯器有關的東西的影響。程序員如果關心效率,應該實際測試,不要光憑推論或常識判斷或假設。優化操作并不一定總是能夠有效運行。

2002-7-15

3.6 指向Data Members的指針
指向data members的指針可用來詳細調查class members的底層布局,可用來決定vptr是放在class的起始處還是尾端,還可用來決定class中access sections的次序。

取一個nonstatic data member的地址,將會得到它在class的offset;而取一個static data member的地址或者取一個綁定于真正class object身上的data member的地址,將會得到該member在內存中的真正地址。這也正是someType someClass::*和someTye *潛在的區別。

2002-7-16

Function語意學 The Semantics of Function
C++支持三種類型的member functions:static、nonstatic和virtual,每一種類型的調用方式都不同。

4.1 Members的各種調用方式
1.   C++的設計準則之一便是nonstatic member function至少必須和一般的nonmember function有著相同的效率。編譯器內部會將member函數實體轉換為對等的nonmember函數實體,其步驟為:

ü          改寫函數原型signature以安插一個額外的參數this到member function中,使得class object可以調用該函數。其中,this是const指針,若該函數為const,則反映在this上面的結果是this指向的data也為const;

ü          將每一個對nonstatic data member的存取操作改為經由this指針來存取;

ü          將member function重新寫成一個外部函數,對函數名稱進行mangling處理;

此后,每一個函數調用操作也都必須轉換,用以提供相應的實參。

2.   關于虛擬函數的內部轉換步驟:若normalize是一個virtual member function,ptr->normalize();會被內部轉化為(*ptr->vptr[t])(ptr); 事實上,vptr名稱也會被mangled,因為可能存在有多個vptrs;t是vitrual table slot的索引值,關聯到normalize函數;第二個ptr表示this指針。

3.   使用class scope operator明確調用一個vitual function,或經由一個class object調用一個vitual function其決議方式會和nontatic member function一樣!故virtual function的一個inline函數實體可被擴展開來,因而提供極大的效率利益。

4.   static member function的主要特征是沒有this指針,這導致它不能直接存取其class中的nonstatic members,不能被聲明為const、volatile或virtual,也不需要經由class object才能調用。static member function會被提出于class聲明之外,并給予一個經過mangled的適當名稱。如果取一個static member function的地址,得到的將是其在內存中的地址,其地址類型并不是一個指向class member function的指針,而是一個nonmember函數指針。static member function的一個意想不到的好處是可以成為一個callback函數,也可以成功地應用在thread函數身上。

2002-07-17

4.2 Virtual Member Functions虛擬成員函數
1.   C++中,多態polymorphism表示以一個public base class指針或reference尋址出一個derived class object。識別一個class是否支持多態,唯一適當的方法試看它是否有任何virtual function。只要class擁有一個virtual function,它就需要一份額外的執行期型別判斷信息。

2.   一個class只會有一個virtual table,其中內含對應class object中所有的active virtual functions的函數實體的地址。這些active virtual functions包括:

ü          一個class定義的函數實體。它會改寫overriding一個可能存在的base class virtual function。

ü          繼承自base class的函數實體。此時該class不改寫base class virtual function。

ü          一個pure_virtual_called()函數實體,它既可以扮演pure virtual function的空間保衛者,也可以當作執行期異常處理函數。如果該函數被調用,通常的操作是結束程序。

3.   每一個virtual function都被指派一個固定不變的索引值,該值在整個繼承體系中保持與特定virtual function的關聯。這樣就可以在編譯時期設定virtual function的調用。

2002-7-20

4.   多重繼承下,一個上層basse classes數目為n的derived class,它將內含n-1個額外的virtual tables。其主要實體與最左端的base class共享,其中包含所有virtual functios的地址;n-1個次要實體與其它base classes有關,其中只包含出現在對應base class中virtual functions的地址。

5.   在多重繼承中支持virtual function,其復雜度圍繞在第二個及后繼base class上,以及執行期this指針調整上。第二(或后繼)base class會影響對virtual function支持的3種情況:

ü          通過指向第二個base class的指針,調用derived class virtual function;

ü          通過指向derived class的指針,調用第二個base class中一個繼承而來的virtual function;

ü          允許virtual function函數的返回值類型有所變化,可能是base type,也可能是publicly derived type。

6.   關于執行期this指針調整比較有效率的解決方法是thunk。所謂thunk是一小端assembly碼,用來以適當的offset值來調整this指針并跳到相應的virtual function。thunk技術允許virtual table slot繼續內含一個簡單的指針,此時多重繼承將不需要任何空間上的額外負擔!slots中的地址可以直接指向virtual function,也可以指向一個相關的thunk。

4.3 函數的效能
nonmember、static member和nonstatic member function在內部都會轉化為完全相同的形式,三者效率相同。

2002-08-08

4.4 指向Member Function的指針
對一個nonstatic member function取址,得到的是該函數在內存中的地址;而面對一個virtual function,得到的將是一個索引值。這個值是不完整的,必須被綁定于一個class object上,才能夠通過它調用函數。指向member function的指針的聲明語法,以及指向member selection運算符的指針,其作用是作為this指針的空間保留者。因此,static member function的類型是函數指針,而不是指向member function的指針。

使用一個member function指針,如果并不用于virtual function、多重繼承、virtual base class等情況的話,其成本并不比使用一個nonmember function指針要高。

4.5 Inline Functions
關鍵詞inline只是一項請求。如果在某個層次上,函數的執行成本比一般的函數調用及返回機制所帶來的負荷低,那么該請求被接受,編譯器就用一個表達式合理地將函數擴展開來。真正的inline函數擴展操作是在函數調用的那一點上。在inline擴展期間,每一個形式參數會被對應的實際參數所取代,inline函數中的每一個局部變量都必須被放在函數調用的一個封閉區段中,并擁有一個獨一無二的名稱。這會帶來參數的求值操作以及臨時性對象的管理。

2002-08-11

構造、解構、拷貝語意學  Semantics of Construction, Destruction, and Copy
1.   一般而言,class的data member應該被初始化,而且只在constructor中或其它member functions中初始化,其它任何操作都將破壞其封裝性質,使其維護和修改更加困難。

2.   可以定義并調用invoke一個pure virtual function,但它只能被靜態調用,不能經由虛擬機制調用。每一個derived class destructor會被編譯器加以擴展,靜態調用每一個virtual base class以及上一層base class的destructor。因此,不管base class的virtual destructor是否聲明為pure,它必須被定義。

5.1 無繼承情況下的對象構造
C++ Standard要求編譯器盡量延遲nontrivial members的實際合成操作,直到真正遇到其使用場所為止。

5.2 繼承體系下的對象構造
一般而言,繼承體系下編譯器對constructor所作的擴充操作以及次序大約如下:

ü          所有virtual base class constructors必須從左到右、從深到淺被調用:如果class被列于member initialization list中,那么任何明確指定的參數都必須傳遞過去,否則如果class有一個default constructor,也應該調用它;class中的每一個virtual base class subobject的偏移量offset必須在執行期可被存取;如果class object是最底層most-derived的class,其constructors可能被調用,某些用以支持這個行為的機制必須被方進來。

ü          以base class的聲明次序調用上一層base class constructors:如果base class被列于member initialization list中,那么任何明確指定的參數都必須傳遞過去,否則若它有default constructor或default memberwise copy constructor,那么就調用它;如果base class是多重繼承下的第二或后繼的base class,那么this指針必須有所調整。

ü          如果class object有virtual table pointer(s),它(們)必須被設定初值,指向適當的virtual table(s)。

ü          如果有一個member沒有出現在member initialization list中,但它有default constructor,調用之。

ü          將member initialization list中的data members的初始化操作以members的聲明次序放進constructor的函數本身。

2002-8-18

5.3對象復制語意學 Object Copy Semantics
1.   只有在默認行為所導致的語意不安全或者不正確以致發生別名化aliasing或者內存泄漏memory leak時,才需要設計一個copy assignment operator。否則,程序反倒會執行得較慢。

2.   如果僅僅是為了把NRV優化開關打開而提供一個copy constructor,那么就沒有必要一定要提供一個copy assignment operator。

3.   copy assignment operator有一個非正交情況,那就是它缺乏一個平行于member initialization list的member assignment list。調用base class的copy assignment operator示例:

Point::operator = (p3d); 或 (*(Point*)this) = p3d; 或 (Point &)(*this) = p3d;

4.   事實上,copy assignment operator在虛擬繼承情況下行為不佳,需要小心設計和說明。許多編譯器甚至并不嘗試取得正確的語意,它們在每一個中間的copy assignment operator中調用每一個base class instance,于是造成virtual base copy assignment operator的多個實體被調用。建議盡可能不要允許一個virtual base class的拷貝操作,并不要在任何virtual base class中聲明data member。

5.5解構語意學 Semantics of Destruction
如果class沒有定義destructor,那么只有在其內帶的member object或base class擁有destructor時,編譯器才會自動合成出一個destructor。一個由程序員定義的destructor被擴展的方式類似constructors被擴展的方式,只是順序相反:

ü          destructor的函數本體首先被執行;

ü          如果class擁有member class objects,而后者擁有destructors,那么它們將以聲明的相反順序而調用;

ü          如果object內帶一個vptr,則現在被重新設定以指向適當base class之virtual table;

ü          如果有任何直接的nonvirtual base classes擁有destructor,它們將以聲明的相反順序而調用;

ü          如果有任何virtual base classes擁有destructor,而前面討論的這個class是most-derived class,那么它們會以原先構造順序的相反順序被調用。

2002-8-19

執行期語意學 Runtime Semantics
6.1對象的構造和解構
1.   一般而言,constructor和destructor的安插都如你所預期。但如果一個區段或函數中有一個以上的離開點,情況就會復雜一些,destructor會放在每一個離開點之前。通常,我們要求將object盡可能放在使用它的那個程序區附近,這樣做可以節省不必要的對象產生和銷毀操作。

2.   C++程序中所有的global objects都被放置在程序的data segment中,如果不明確指定初值,object所配置的內存內容將為0(C并不自動設定初值)。如果global object有constructor和destructor的話,我們說它需要靜態的初始化和內存釋放操作。

2002-8-20

3.   virtual base class的subobject在每個derived class中的位置可能會變動,不能在編譯時期確定。以一個derived class的pointer或reference來存取virtual base class subobject,是一種nonconstant expression,必須在執行期方可評估求值。

4.   使用靜態初始化的object有一些缺點。其一,無法放入try區段,任何throw操作必將觸發exception handling library的默認函數terminate();其二,程序員必須為控制“需要跨越模塊做靜態初始化”objects的依賴順序而產生的復雜度付出代價。建議根本就不要使用那些需要靜態初始化的global objects。

5.   新的C++標準要求編譯單位中的static local class objects必須在相應函數第一次被調用時才被構造,而且必須以相反的次序銷毀。由于這些objects是在需要時才被構造,因此編譯時期無法預期其集合和順序。為支持新標準,可能要對被產生出來的static local class objects保持一個執行期鏈表。

2003-8-1

6.   對于對象數組定義,晚近的編譯器一般會提供兩個函數,分別用于處理沒有virtual base class的class,以及內帶virtual base class的class ,它們通常被稱為vec_new、vec_vnew。前者類型通常為:

void* vec_new(                                                   // 初始化程序員未提供初值的連續元素

           void *array,                                               // 數組起始地址若為0,則動態分配

           size_t elem_size,                                       // 每一個class object的大小

           int elem_count,                                         // 數組中的元素數目

           void (*constructor) (void *),                    // class的default constructor指針

           void (*destructor) (void *, char)               // class的destructor指針,以0填入

); 如果程序員提供帶有默認參數值的default constructor,編譯器要做特殊處理,以傳入默認參數值!

對應銷毀數組的兩個函數分別為vec_delete、vec_vdelete。前者類型通常為:

void* vec_delete(

           void *array,                                               // 數組起始地址

           size_t elem_size,                                       // 每一個class object的大小

           int elem_count,                                         // 數組中的元素數目

           void (*destructor) (void *, char)               // class的destructor指針

);

6.2 new和delete運算符
         注意區分operator new和new operator!前者負責分配內存;后者先調用前者分配內存,然后調用constructor以實施初始化。

《深度探索C++對象模型》讀書筆記

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/xjtuse_mal/archive/2007/03/01/1517809.aspx

posted on 2010-10-14 10:36 Vincent 閱讀(440) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产精品久久一级| 亚洲新中文字幕| 一区二区日韩精品| 狂野欧美激情性xxxx| 亚洲调教视频在线观看| 欧美日韩精品综合在线| 日韩视频永久免费观看| 最新国产精品拍自在线播放| 亚洲免费在线视频| 国产精品免费一区二区三区在线观看| 在线一区视频| 一区二区不卡在线视频 午夜欧美不卡在 | 免费的成人av| 欧美一区激情| 欧美日韩免费观看一区二区三区| 一区二区在线不卡| 久久久久久夜精品精品免费| 午夜日韩在线观看| 韩日精品在线| 欧美成人乱码一区二区三区| 欧美ab在线视频| 艳女tv在线观看国产一区| 日韩一区二区精品| 国产乱码精品一区二区三区忘忧草| 午夜日韩激情| 久久婷婷综合激情| 亚洲激情欧美| 亚洲欧美日韩在线综合| 红杏aⅴ成人免费视频| 亚洲国产精品99久久久久久久久| 欧美一激情一区二区三区| 亚洲小说欧美另类社区| 国产精品久久久| 欧美激情精品久久久久久久变态| 欧美巨乳在线| 久久久精品动漫| 在线综合视频| 在线免费观看日韩欧美| 亚洲国产精品综合| 国产欧美一区二区三区另类精品 | 美女999久久久精品视频| 噜噜噜噜噜久久久久久91| 制服丝袜亚洲播放| 久久久亚洲综合| 欧美中文字幕久久| 欧美三级不卡| 亚洲电影免费观看高清| 国产欧美日韩激情| 一区在线免费观看| 亚洲午夜av在线| 日韩午夜在线观看视频| 免费一级欧美片在线播放| 久久久不卡网国产精品一区| 欧美三日本三级少妇三2023| 欧美激情视频免费观看| 黄网站免费久久| 午夜精品久久久久久99热| 亚洲视频一区在线| 欧美精品在线一区二区| 91久久精品国产91性色| 最新国产成人在线观看| 久久久亚洲高清| 欧美成人国产| 亚洲国产91精品在线观看| 久久噜噜噜精品国产亚洲综合| 久久国产精品久久久久久电车| 欧美国产日韩一区二区| 亚洲久久视频| 亚洲午夜在线视频| 国产精品视频一区二区高潮| 欧美一级播放| 久久精品亚洲热| 亚洲国产精品成人综合色在线婷婷| 久久久99精品免费观看不卡| 免费成人高清视频| 欧美日产国产成人免费图片| 99成人精品| 久久精品日韩一区二区三区| 精品二区视频| 欧美午夜不卡视频| 欧美一区二区三区久久精品| 欧美a级一区| 亚洲欧美中文字幕| 免费亚洲电影| 欧美高清在线视频观看不卡| 99热免费精品| 韩日精品在线| 国产精品美女主播在线观看纯欲| 久久精品卡一| 亚洲精品视频在线观看网站| 久久成人国产精品| 日韩视频在线观看国产| 国产亚洲一级| 欧美日韩亚洲综合| 久久久久久久久久久久久女国产乱| 亚洲乱码国产乱码精品精| 久久精品麻豆| 亚洲黄色免费电影| 好男人免费精品视频| 麻豆精品网站| 午夜精品短视频| 日韩亚洲欧美中文三级| 久热国产精品视频| 欧美一区二区三区在线观看| 日韩视频不卡| 亚洲激情国产精品| 在线看日韩欧美| 国产一区久久久| 国产精品一区久久久久| 国产精品久在线观看| 欧美国产精品劲爆| 欧美国产日韩精品| 欧美成人免费在线视频| 亚洲欧美国产日韩中文字幕| 亚洲电影在线看| 欧美激情精品久久久六区热门 | 亚洲视频在线观看免费| 亚洲日本va午夜在线电影| 免费h精品视频在线播放| 欧美成年人视频网站| 麻豆成人在线观看| 亚洲国产欧美日韩| 亚洲区一区二| 亚洲免费一在线| 久久九九全国免费精品观看| 久久精品人人做人人综合| 麻豆免费精品视频| 欧美国产高潮xxxx1819| 亚洲国产精品久久久久久女王| 亚洲大胆人体视频| 99xxxx成人网| 亚洲欧美日韩一区在线| 久久国产主播| 欧美国产另类| 国产精品手机在线| 国模精品娜娜一二三区| 99视频精品| 久久久久久久一区二区| 亚洲日韩中文字幕在线播放| 中文日韩在线| 久久久久久9999| 欧美日韩在线播放三区四区| 狠狠狠色丁香婷婷综合久久五月| 亚洲精品偷拍| 久久成人18免费观看| 亚洲国产欧美一区| 欧美怡红院视频| 欧美日本中文| 亚洲人成网站999久久久综合| 亚洲欧美日韩人成在线播放| 欧美激情一区二区三区成人| 亚洲欧美一区二区精品久久久| 欧美aa在线视频| 一区二区自拍| 亚洲精品专区| 欧美国产视频在线观看| 欧美一区二区高清| 国产精品毛片在线| 亚洲乱亚洲高清| 毛片一区二区三区| 午夜久久黄色| 国产精品亚洲激情| 亚洲免费一区二区| 夜夜夜精品看看| 欧美日韩爆操| 亚洲一区二区三区四区五区午夜 | 久热精品视频在线观看| 好看的日韩视频| 亚洲午夜精品网| 怡红院精品视频| 艳女tv在线观看国产一区| 亚洲高清一区二| 欧美成年人网| 激情av一区二区| 欧美电影在线| 欧美日韩国产黄| 性色av一区二区三区红粉影视| 欧美一区二区三区久久精品 | 99re国产精品| 欧美肉体xxxx裸体137大胆| 美女黄毛**国产精品啪啪| 亚洲精品精选| 一区二区三区欧美在线观看| 国产精品一区二区三区观看| 久久大逼视频| 欧美激情视频一区二区三区免费| 一区二区三区高清视频在线观看| 一区二区三区蜜桃网| 国产午夜精品视频| 亚洲制服av| 久久国内精品视频| 亚洲黄色免费| 亚洲婷婷免费| 91久久精品久久国产性色也91| 一本大道久久a久久综合婷婷| 极品少妇一区二区| 国产精品99久久不卡二区| 欧美日韩国产一区| 久久五月天婷婷| 国产精品大片|