在之前的章節中,已經知道取乙個nonstatic data memeber的位址,得到的結果就是該member在class布局中的bytes位置(再加上1),我們知道的是,它是乙個不完整的值,它需要被繫結於某個class object的位址上,才能被訪問。
取乙個nonstatic member function的位址,如果該函式是nonvirtual ,則得到的結果是它在記憶體中真正的位址,但是這個值也是不完全的,它也需要被繫結於某個class object的位址上,才能通過它呼叫該函式。所有的nonstatic member functions都需要物件的位址。
float (point::*pmf)() =&point::z;
point *ptr=new point3d();
pmf,乙個指向member function的指標,被設值為point::z()(乙個virtual function)的位址。
ptr則被指定以乙個point3d物件,如果我們直接經由ptr呼叫z():ptr->z();
則被呼叫的是point3d:?(),但如果我們從pmf間接呼叫z():(ptr->*pmf)();
在虛擬機制的作用下,point3d:z()被呼叫。那麼它是如何實現的呢?
在之前講過,對乙個nonstatic member function取其位址,將獲得該函式在記憶體中的位址。然而如果面對乙個virtual function,其位址在編譯時期也是未知的,所能知道的僅是virtual function與其相關的virtual table中的索引值。也就是說,對乙個virtual memeber function取其位址,所能獲得的只是乙個索引值。
為了讓指向member functions的指標也能支援多重繼承和虛擬繼承,
當函式cross_product()函式經由以下方式呼叫:
關鍵字inline只是一項請求,如果這項請求被接受,編譯器就必須認為他可以用乙個表示式合理的將整個函式擴充套件開。這裡的「編譯器相信它可以合理地擴充套件乙個inline 函式」時,就是說在某個層次上,其執行成本比一般的函式呼叫及返回機制所帶來的負荷低。
一般而言,處理乙個inline函式,有兩個階段:
在inline擴充套件期間,每乙個形式引數都會被對應的實際引數取代。如果說有什麼***,就是可能會引入臨時性物件。也就是說,如果實際引數是乙個常量表示式,我們可以在替換之前先完成其求值操作:後繼的inline替換,就可以把常量直接「綁」上去。如果既不是常量表示式,也不是有***的表示式,那就就可以直接替換。
inline int
min(int i,intj)
{return i那麼標記為(1)的那一行會被擴充套件為:
//(1)引數直接替換為
minval=val1那麼標記為(2)的那一行會直接替換為常量:
//(2)代換之後,直接使用常量
minval=1024;
那麼標記為(3)的那一行則會引發引數的***,它需要匯入乙個臨時物件,以避免重複求值:
//(3)有***,所以匯入臨時物件
int t1,t2;
minval=
(t1=foo()),(t2=bar()+1),
t1如果我們改變以上函式的定義,在inline定義中加入乙個區域性變數,那麼就會:
inline int
min(int i,int j)
{ int minval=i這個區域性變數需要什麼額外的支援或處理呢?
inline被擴充套件開之後,為了維護其區域性變數,可能會成為下面這個樣子:
{int local_var;
int minval;
//將inline 函式的區域性變數處以「mangling」操作
int __min_lv_minval;
minval=
(__min_lv_minval=
val1一般而言,inline函式中的每乙個區域性變數都必須被放在函式呼叫的乙個封閉區段中,擁有獨一無二的名稱。如果inline函式以單一表示式擴充套件多次,那麼每次擴充套件都需要自己的一組區域性變數。如果inline函式以分離的多個式子被擴充套件多次,那麼只需要一組區域性變數,就可以重複使用。
inline函式中的區域性變數,再加上有***的引數,可能會導致大量臨時性的物件的產生。
inline函式對於封裝提供了一種必要的支援,可以有效訪問封裝與class中的nonpublic資料。它同時也是c程式中大量使用的#define的乙個安全替代品。然而乙個inline函式如果被呼叫太多次,會產生大量的擴充套件碼。
引數帶有***,或是以乙個單一表示式做多重呼叫,或是在inline函式中有多個區域性變數,會產生臨時性物件,編譯器也許能(也許不能)夠把它們移除。
inline中如果再有inline,可能會使乙個表面上看起來平凡的inline卻因其連鎖複雜度而沒辦法擴充套件開來。
與non-inline函式比起來,inline需要更加小心的處理。
第四章 模型
1 資料庫配置 在setting.py中資料庫設定連線資訊設定如下 databases 在專案下的 init py中新增資料庫匯入 import pymysql 配置mysql引用 pymysql.install as mysqldb 乙個作者有姓,有名及email位址。出版商有名稱,位址,所在城市...
第四章 物件
三個特性 身份 型別 值 每個物件都有唯一的身份來標識自己,使用內建函式id 得到。例子 usr bin env python coding utf 8 a 32 print a b a print id a id b 結果 d python27 python.exe e workp python ...
第四章筆記
一.引入樣式 1.行內樣式表 2.內部樣式表 在head標籤裡面,title標籤下面 優點方便在同頁面中修改樣式 缺點不利於在多頁面間共享復用 及維護,對內容與樣式的分離也不夠徹底 3.外部樣式表 嵌入式匯入式 嵌入式和匯入式的區別 1.標籤屬於xhtml,import是屬於css2.1 2.使用鏈...