你檢索你的對象是這樣的:
Libitem* old_book = catalog[1];
就這樣,編譯器只知道你有一個名爲類型的old_book
指針Libitem
變量。如果你自己單獨閱讀特定行,你會注意到,唯一的這是你和編譯器當時唯一的信息。當你自己讀這行的時候就是編譯時間。通過閱讀代碼你可以知道什麼。
當程序實際運行,該變量可以指向Book
類型的對象。但是這隻在程序運行時才知道,因此,運行時間。
名稱查找發生在C++編譯時。當你調用一個函數的對象上是這樣的:
// Type of an_object is a_struct
a_struct an_object;
an_object.member_function();
編譯器將着眼於可用的功能裏面a_struct
。由於編譯器正在聲明結構體中的名稱,所以在編譯時真正解析了名稱。
讓我們回到你的案例。你有一個指向Libitem
的指針。如果您嘗試使用箭頭來訪問它裏面的東西:
old_book->something
要解決什麼something
是,編譯器會往裏Libitem
它,因爲old_book
類型是一個指向Libitem
。即使指針指向一個子類的實例,唯一的編譯器知道肯定是對象的實際類型指出,至少Libitem
。現在
,你的人知道比編譯器的更多。你知道指針old_book
指向類Book
的一個實例。您想訪問Book
的會員。
爲此,您必須明確告訴編譯器您想使用來自子類的成員。要做到這一點,你的變量必須是Book
的類型,所以編譯器會查找適當的類。爲此,您可以將您的變量轉換爲另一種類型。由於您將變量轉換爲層次結構中較低級別的變量,因此將其稱爲向下傾斜。那種鑄鐵的,我們可以在這種情況下使用是dynamic_cast
,一個演員,其中將着眼於運行的是由指針所指向的實際類型的實例:
if (Book* the_old_book = dynamic_cast<Book*>(old_book)) {
// We can use the_old_book here, which his type is Book!
} else {
// The cast failed, the real for of the variable is not Book,
// and the_old_book points to nullptr
}
正如你所看到的,我們創建了一個新的指針名爲the_old_book
,它由演員的結果初始化。如果old_book
指向的實例的實際類型實際上不是Book
,則該投射將失敗並返回nullptr
。由於這發生在運行時,我們必須使用運行時分支驗證我們的新變量,if
。如果轉換失敗,則執行的塊將爲else
塊。
請搜索並閱讀關於* downcasting *。 –