2013-05-05 70 views
1

這是一個相當複雜的問題。所以我有一個絕對抽象的基類和3個派生類(A,B,C)。使用基類的操作符>>創建派生類

使用std::ifstream& operator>>(std::ifstream& ifs, Base* a) 我有一個是設置這樣的一個文件:

有5 2

B 2 3

每行以任一A開始, B,C告訴我我得到的類的類型,然後是這個類的實際值。

int a, b; 
std::string what; 
ifs >> what >> a >> b; 
if (what == "A") 
{ 
    //create an A class using a, and b. 
} 
從基礎運營商

所以>> I必須調用派生類的功能之一,最終「A」(基本*)會得到一個a,從funcion返回B或C類,和我在一個異構集合中保存'a'。

這可能嗎?我如何做到這一點,感覺就像我只是在我需要基類中的派生類和派生類中的基類中創建一個圓。

+1

請參閱:http://stackoverflow.com/questions/1080448/best-practice-for-list-of-polymorphic-objects-in-c – 2013-05-05 16:06:56

+0

謝謝,這似乎與我的問題非常相似。 – SaintHUN 2013-05-05 16:45:01

回答

0

真的需要派生類嗎?根據您提供的信息和代碼,我看不出有什麼「A」,「B」和除其類型「C」之間的區別,所以我想出了下面的代碼:

#include <string> 
#include <iostream> 
using namespace std; 

class foo { 
public: 
    foo(int aa = 0, int bb = 0, int tt = 0) 
     : a(aa), b(bb), tp(tt) {} 

    // void set_type(int t) { tp = t; } 
protected: 
    int a, b, tp 
}; 

int main() { 
    char t; 
    int a, b; 
    while (cin >> t >> a >> b) { 
     foo f(a, b, t-'a'); 
    } 
} 
+0

從此不清楚,但是我確實需要全部3個派生類。 – SaintHUN 2013-05-05 16:20:37

1

製作一個工廠函數可能更有意義,它可能是Base()的一個靜態成員;

如果你想保持目前的結構,我認爲你可以解決這個問題是這樣的:

std::ifstream& operator>>(std::ifstream& ifs, Base* a){ 
    // remove whatever object you currently have in a 
    if(a!=NULL) delete a; 

    // standard factory 
    // e.g. read what you need to determine the correct derived class 
    // and call its constructor 
    int a, b; 
    std::string what; 
    ifs >> what >> a >> b; 
    if (what == "A") 
    { 
     //create an A class using a, and b. 
     a = new A(a,b); 
    } 
    ... 
} 

編輯:您可能需要在原型中使用的引用基類指針:

std::ifstream& operator>>(std::ifstream& ifs, Base *&a){ ... } 
+0

爲了調用派生類,我必須將它們放在基類之上,並且在派生類中使用基類,我必須將基類放在派生類之上,這是我的理解。這不會導致問題嗎? – SaintHUN 2013-05-05 16:30:48

+0

@SaintHUN如果你需要,也許你可以做[forward declaration](http://stackoverflow.com/questions/553682/when-to-use-forward-declaration)。 – gongzhitaao 2013-05-05 16:33:50

+0

也許我誤解了你的問題,但你可以在實現它們之前定義類和它們的成員函數。如果需要,基類成員函數的實現可以使用派生類。在這種特殊情況下我沒有看到任何問題,因爲您只是將派生對象構造爲基指針。 – 2013-05-05 16:38:17

0

我設法使用幫助從這個鏈接來解決我的問題:thanks Scott Jones

基本上我創建了一個特殊的功能,其全部目的是爲了弄清楚它需要哪一類s創建(A,B,C)並將其發回處理。

Base* Deserialize(std::ifstream &ifs) 
{ 
Base *temp; 
std::string what; 
ifs >> what; 
if (what== "A") 
    { 
     temp = new A(); 
     return temp; 
    } 
} 

這個工作的原因是因爲這是基類和派生類之外的特殊函數,它可以查看和使用它們。

+0

這被稱爲工廠方法。這是我要建議的模式。 – UpAndAdam 2013-05-06 17:49:52