注意:如果你是乙個初學者,對例項方法,虛方法的呼叫還不太清楚,強烈建議你不要閱讀本文,因為這裡面的**會讓你完全崩潰掉。
如果你對例項方法,虛方法的執行機制已經瞭如指掌,並且,對方法和物件的記憶體布局也心中有數,那麼本文可能會顛覆你以前對他們的認識。
閱讀本文的最佳方式就是親自演練一下,如果看完之後有疑惑,那麼是正常的,但是稍加思考就會想明白。
我說,string變數可以直接引用乙個object物件!
我說,派生型別的變數可以直接引用基型別的物件!
你會說,老兄,別開玩笑了,派生型別怎麼可以指向乙個基型別的物件呢!
我會讓你見證一下奇蹟,並在文章的結尾再給你乙個更加不可思議的例子。
首先,請看下面的**:
class毫無疑問,在執行時一定會丟擲乙個異常,因為base物件無法轉換為derived物件。program
}class
base
}class
derived : base
}
但是,現在,我就想讓d指向base物件,並且可以呼叫base中的print方法,該怎麼做呢?
用filedoffset可以做到這一點,但首先需要定義乙個叫做manager的類,裡面包含兩個例項字段,乙個為derived,乙個為base。如下:
[structlayout(layoutkind.explicit)]現在,通過為b和derived都指定了相同的偏移,所以,b和derived都指向了同乙個物件,base物件。class
manager
由於derived現在指向了base物件,那麼如果我呼叫d.print方法,呼叫的是base的printf還是derived的print方法,還是丟擲乙個異常。請看如下**:
class執行上面**,會輸出什麼呢?program
}
答案是,「in derived」。
這很不可思議,因為derived指向的是base物件,現在呼叫的確實derived的方法。想要了解原因,請看下圖:
這裡,儘管derived指向的是乙個base物件,但是,clr發現print是乙個非虛方法,所以clr並不關心derived變數指向什麼物件,clr根據derived變數的型別來呼叫print方法,這裡derived是乙個derived型別,所以clr會呼叫derived中的print,最終輸出in derived。
第二個例子:
下面的這個例子也很不可思議,同樣會顛覆你傳統的觀點。
讓我們將上面的print方法改為virtual方法,最終如下:
[structlayout(layoutkind.explicit)]現在,執行如下測試**:class
manager
class
base
}class
derived : base
}
class這次結果會是什麼呢?強烈建議你自己思***。program
}
結果是,in base!
是不是及其不可思議!為了更清楚的理解原因,請看下圖:
這裡,儘管derived指向的是base物件,但是,當clr看到derived.print這行**時,由於print是虛方法,所以clr會檢視derived所指向的base物件。
clr發現base物件裡的type object pointer指向乙個base type object,於是就呼叫base type object中的print方法,所以最終會輸出inbase。
總結:沒有總結可不好。
本質上,子型別是不能引用父型別物件的。但是,我們可以通過fieldoffset繞過這一限制。通過子型別的變數來呼叫父物件的方法,這很是不可思議,但更不思議的是,當子型別的變數指向父物件時,竟然可以呼叫子方法!
那麼上面的本質是什麼呢?當clr呼叫乙個非虛方法時,不會關心變數具體指向的是什麼,因為clr此時是通過變數的型別來呼叫方法。如果方法時虛方法,那麼clr為了實現多型,需要檢視這個變數指向的是什麼物件,然後在通過物件的type object pointer找到對應的type object,然後呼叫type object中的方法。
對方法的驗證
1 把基準資料提出 import pandas as pd dframe1 pd.read excel window regulator分析報告分析.xlsx sheetname sheet1 dframe2 pd.read excel window regulator分析報告分析.xlsx she...
子窗體與父窗體呼叫對方js方法
有時候為了減少乙個頁面內的 量,會將部分內容放到子窗體中,如後台管理中用iframe來進行管理 dviframe src 1 在父窗體獲取子窗體的windows物件 var formwindow dviframe 0 contentwindow 0 是jq物件轉換成dom物件,再獲取子窗體windo...
領導力提公升 你找對方法了嗎?
自製是領導力提公升中領導者面臨的最大的考驗。領導者的一舉一動都會向員工傳達一定的資訊。因此,領導者應該謹慎行事。頌揚 謙遜或憤怒的言辭能夠增強或損毀領導者的影響力。員工會審視領導者的一舉一動。他們是否願意追隨領導者也將受到領導者行為的影響。人們可能會忽視自己的行為及其影響。但是,領導者不能無視自己的...