2013-11-25 52 views
1

假設我有這樣的:通過它鑄造派生並設置數據擴展基類

class Base { 
public: 
    int a; 
    Base() : a(5) {} 
}; 

template<class T> 
class Derived : public Base { 
public: 
    T value; 
}; 

以下作品中的代碼,但我想知道什麼可以使用這種方法的挑戰:

Base * base = new Base; 
Derived<int> * derived = static_cast<Derived<int>*>(base); 
derived->value = 5; 
Derived<String> * derived1 = static_cast<Derived<String>*>(base); 
derived1->value = "test"; 

Derived<String> * newderived = static_cast<Derived<String>*>(base); 
std::cout << newderived->value; 
Derived<int> * newderived1 = static_cast<Derived<int>*>(base); 
std::cout << newderived1->value; 
//Output: test1 

或者我怎樣才能以不同的,更安全的方式實現這樣的事情。我想通過5個函數傳遞一個類來處理它。

+1

簡單的解決方案,因爲他們在c + +書籍編寫,大多是好的。我建議你從簡單的,基於繼承的,無模板的最小示例開始。試試這個,再次問我們,_that_有什麼問題。 – peterh

+2

「作品」在這裏似乎有點誇大其辭。您正在覆蓋未分配的內存,這會在程序的某個稍後階段導致未指定但可能導致災難性的問題。 (嘗試使用valgrind獲取更多詳細信息。) – rici

+5

代碼具有未定義的行爲,如果它對您有用,那是因爲您很不幸。 – john

回答

2

你在這裏做的事情會在某個時候失敗,因爲派生類的大小大於基類,並且你在基類結束後編寫。上述寫入操作將覆蓋屬於另一個對象的內存。 您可以在基類中擁有一個SetValue()方法,並在派生類中實現它。

2

該代碼不起作用。即使在鑄造後你仍然會反對,因爲你將它們構建爲基礎。演員們只是說:嗨,我知道這是一個Derived<xxx>,所以請您這樣解釋。這裏你不知道,事實上你知道它不是Derived

要正確使用這些對象,您需要創建一個Derived<xxx>並在事後投射。如果您在此處使用dynamic_cast,則所有情況都應該返回爲空,因爲它們是Base

鑑於您想「通過5個功能傳遞課程」,您可能需要反向設置。創建Derived<xxx>對象並將它們保存爲指向Base的指針。這可以在沒有鑄造的情況下工作。然後通過你的功能通過Base*。多態性將保證一切正常。

+0

我不應該創建派生類。所以我正在考慮爲基類添加一個元素的容器。 – Gasim

+0

您正在定義「派生」類,但不應該使用它們?這對我來說沒有任何意義。你必須更清楚地說明你想解決的實際問題。 – dornhege

+0

我的意思是,傳遞給函數的第一個對象通常是基類。所以,我擺脫了派生類,試圖找到一種方法將多類型數組添加到可以隨時分配的基類中。 – Gasim