2009-12-04 75 views
1

這個問題看起來可能有些常見,但是在放大StackOverflow或interwebs時我沒有找到任何東西。在處理父類對象列表時調用Child類的方法

我遇到了一個C++類中的方法,該類使用(例如)Parent對象的列表。對於此示例,假設有兩個類別從ParentChild1Child2派生。

對於列表中的每個對象,所述方法檢查如果對象是Child2類型(通過IsOfType()方法,每個類實現)的,並且如果是這樣,它調用僅由Child2類提供了一種方法。

這是一個問題,因爲列表處理方法不能將每個對象都視爲相同嗎?我在其他地方也看到了這一點,所以在某種程度上它似乎是一種常見的做法。

一個選項可能是在Parent類中聲明Child2方法,以便所有Parent對象實現它。但是,在這種情況下,只有Child2類實際上會在覆蓋該方法時實現任何行爲。

您的想法?提前致謝!

回答

1

如果您的IsOfType()測試通過,您可以將(指向父對象的)指針轉換爲Child2對象並訪問其特定的成員函數。

編輯: 這取決於您的設計以及您確保IsOfType()實施將提供正確答案的嚴格程度(即在一週內添加新的子類時也有效)。改爲使用內置的Typeid可能會更安全。 實現任何孩子在父母身上都會遇到的每種可能的方法都很困難,所以當方法在語義上特別適用於Child2類時,上傳就可以了。

+0

列表處理方法當前的行爲與您所描述的相似,只是它不使用Typeid。也許該方法暫時保持原樣,但可能使用Typeid而不是IsOfType()方法。感謝這個建議! – bporter 2009-12-04 16:57:32

3

我認爲以下是對這個問題更好的解決方案。

class Parent { 
public: 
    virtual int doSomething() {} 
}; 

class Child1 : public Parent { 
}; 

class Child2 : public Parent { 
public: 
    virtual int doSomething(); 

現在您只需完全省略IsOfType調用並在傳遞給您的所有指針上調用doSomething。

我可以想到的爲什麼你有一個IsOfType函數的唯一好理由是,如果你沒有對父類的控制權,並且不能修改它來添加doSomething方法。

+0

如果doSomething有參數並且只有Child2知道這些參數的類型,這是不好的 – 2009-12-04 15:31:48

+2

@Alexey,如果是這種情況,那麼我認爲這是一個糟糕的設計,它不是一個真正適用於多態的問題。 – Glen 2009-12-04 15:35:02

+0

或者,如果在Parent界面中有doSomething()感覺不對,那麼您可能寧願將Child1和Child2實例放在兩個單獨的列表中。也許Child1和Child2沒有足夠的共同性來保證將它們混合在一個列表中。 – digitalarbeiter 2009-12-04 15:37:09

2

您可以在只有Child2實現的接口中聲明新方法。然後,您可以使用dynamic_cast<ISomeOtherInterface>來查看對象是否支持擴展功能。對於不支持額外接口的對象,這種強制轉換將導致null指針。

這將允許您創建實現此功能的其他對象,而無需您的列表處理來了解每個特定的對象類型。

+0

這可能是一個非常好的方法。感謝您的建議! – bporter 2009-12-04 16:59:00

0

在這種情況下,您可能會發現Visitor Pattern有用。這將允許對象本身(child1,child2等)以其靜態類型回叫並採取適當的措施。