2010-04-01 94 views
4

我有一個自定義類Student對象的數組。 CourseStudent和ResearchStudent都是從Student繼承而來的,Student的所有實例都是其中的一個。從超類指針訪問子類成員C++

我有一個函數要經過陣列,確定每個學生的亞型,然後調用它們亞型特異性成員函數。

的問題,因爲這些功能都沒有超載,他們沒有在學生中發現,所以編譯器大吵大鬧。

如果我有一個指向學生,有沒有一種方式來獲得一個指向學生的亞型?我是否需要在這裏進行某種假轉換以解決編譯時錯誤?

回答

6

您需要動態演員陣容:

Student * s = new ...; // create student of some sort 

if (ResearchStudent * r = dynamic_cast<ReasearchStudent*>(s)) { 
    r->ResFunc(); 
} 
else if (CourseStudent * c = dynamic_cast<CourseStudent*>(s)) { 
    c->CourseFiunc(); 
} 
else { 
    throw "unknown student type"; 
} 

請注意,它使用由編譯器維護的類型信息,前提是該類至少有一個虛函數 - 如果其他所有函數都失敗,則使析構函數爲虛擬(因爲它必須在此情況下)。你應該總是喜歡這種方法來維護你自己的類型信息。

1

您需要static_cast。由於這些函數不是基類的虛擬成員,因此不能通過指向基類的指針來調用它們。您需要明確地轉換爲對象的實際類型。

這個問題通常是最好的虛擬功能解決了 - 你並不需要的對象類型在你的代碼檢查了,都會有漏洞越少的代碼和麪較少。

2

這是幾乎可以肯定在基類中使用純虛成員函數,然後在派生類中,你做真正的工作壓倒一切的情況下。

9

,最好的辦法是使用虛函數:

class Student 
{ 
    // ... 
    virtual void SpecificFunction() = 0; /* = 0 means it's abstract; it must be implemented by a subclass */ 
    // ... 
}; 

class CourseStudent 
{ 
    void SpecificFunction() { ... } 
}; 

然後,你可以這樣做:

Student *student; 
student->SpecificFunction(); 

A(壞)的替代,可以使用dynamic_cast

Student *student; 
CourseStudent *cs = dynamic_cast<CourseStudent *>(student); 

if (cs) { 
    /* student is a CourseStudent.. */ 
    cs->SpecificFunction(); 
} 
+0

所有的事情都是平等的,Java/C#的視角會說動態轉換更好,因爲這樣你的指針就按你打算使用它的方式被輸入,而不是一個'Student', SpecificFunction()'給出'CourseStudent'的返回值。但我敢肯定,所有的事情都不一樣 - 所以使用動態演員有什麼不好? – 2012-03-21 16:08:36

3

虛擬函數在這裏是不合適的,因爲子類成員函數是特定於這些子類的(例如,CourseStudent有一個單元列表,而ResearchStudent沒有,因此ResearchStudent中的getUnits()函數實現將沒有意義所有)

我對動態和靜態轉換(cplusplus.com typecasting)有一些瞭解,在這種情況下,我認爲靜態轉換更合適。

一個的static_cast的一般缺點是,它在運行時不執行任何檢查,以確保被鑄造到一個子類型的對象是實際上是亞型而不是其他。在這種情況下,我在執行類型之前特別檢查類型(使用在子類構造函數中設置的私有數據成員並且沒有增變器),所以只要我的檢查是好的,靜態轉換就不會有問題。靜態轉換更高效,因爲動態轉換需要更多運行時資源來執行類型檢查。

如果有任何成員不是預期類型的​​機會,靜態轉換就不合適,所以我會去動態轉換(這是一個賦值,因此一旦它被提交,代碼將不需要保持不變,所以不會有人在後面搞亂它)。

+0

我知道這是很久以前,但我想說謝謝;我今天剛剛面對一個非常類似的問題,您的回答爲我提供了完全所需的解決方案! – GarrickW 2012-02-18 17:32:53

+0

@GarrickW很高興聽到它仍然有用 - 使它值得努力尋找想法的解決方案。 – 2012-02-23 03:35:08