2012-08-22 143 views
0

假設您有基類Unix_tree,並衍生出Unix_tree_type1Unix_tree_type2等。爲什麼我無法將Unix_tree投射到Unix_tree_type ...?有沒有辦法演出這樣的演員?派生類包含抽象方法的實現,其目標是以不同方式打印基類中包含的數據。謝謝。類型鑄造問題

class Unix_tree 
    { 
    public: 
     Unix_tree() 
     { 
      tree_it.tree = &tree; 
     } 

     Unix_tree(const Unix_tree& utree) : num_of_files(utree.num_of_files), tree(utree.tree), tree_it(utree.tree_it) 
     { 
      tree_it.tree = &tree; 
     }; 

     int num_of_files; 
     map<int, pair<int, string> > names; 
     vector<pair<int, int> > edges; 

     Tree< pair<int, string> > tree; 
     TreeIterator< pair<int, string> > tree_it; 

     string input_format; 
     string output_format; 

     static Unix_tree* load_tree(istream& input_info); 
     void load_names(istream& input_info); 
     void load_tree_nodes(vector<int>& levels); 
     Unix_tree* convert(string format); 

     virtual void load(istream& input_info) = 0; 
     virtual void print_function(const Tree<pair<int, string> >* node, const vector<bool>& visited) = 0; 
     void print_tree(); 
    }; 


    class Unix_tree_type1 : public Unix_tree 
    { 
    public: 

     void load(istream& input_info); 
     void print_function(const Tree<pair<int, string> >* node, const vector<bool>& visited); 
    }; 
+0

你願意修改這些類嗎?或者你想知道如何使用已存在的內容進行投射? – Beta

+0

你不能實例化'Unix_tree',因爲它包含一個純虛函數。所以你爲什麼需要投它? – corn3lius

+0

也許我有點sl,,對不起。假設你有Unix_tree_type_1,目標是將其轉換爲Unix_tree_type_2。 –

回答

1

可以投三分球,所以:

Unix_tree *p = ...; 
Unix_tree_type1 *q = (Unix_tree_type1*)p; 

但我不認爲你想這樣做。方法調用自動執行你想要的,所以:

Unix_tree *p = ...; // points to an instance of Unix_tree_type1 
p->load(...);  // calls Unix_tree_type1::load, not Unix_tree::load 
+0

C演員是邪惡的! – Rost

+0

我不知道爲什麼,但dynamic_cast後,我收到對象沒有數據的指針。 –

1

你可以投,但你不應該。你應該調用基類所指向的對象的成員函數,並且你的實現將被調用。這是虛擬成員函數的要點。

0

爲什麼你不能?當然,你可以 - 它是有效的upcast,可以通過dynamic_cast完成。但是你應該投入指針或引用,而不是類型本身。

Unix_tree_type1* ptree1 = ...; // Some pointer initialization 
Unix_tree* ptree2 = dynamic_cast<Unix_tree*>(ptree1);// Safe 
Unix_tree* ptree3 = static_cast<Unix_tree*>(ptree1); // Also safe 
1

沒有辦法將基類轉換爲派生類,因爲它沒有任何意義。不用過多的面向對象細節,從基類繼承的目的不僅僅是「打印基類中包含的數據」,而是提供更具體的功能實現。所以想象一下具有「GetJuice()」方法的「水果」類。從「Fruit」繼承的類「Apple」可能會繼承「GetJuice()」方法。但是,除了該方法之外,它還可以定義其他方法或屬性,例如「FindAppleWorm()」,這將與其類型相關。因此,當你有一個Apple類時,你可以將它轉換爲鍵入水果,並且調用Fruit類的「GetJuice()」方法仍然有意義。但是,如果您將Fruit類投射到Apple類,則您可能希望能夠調用「FindAppleWorm()」方法,但它不會存在。

面嚮對象語言中繼承的概念與多態的概念相呼應。我會推薦wikipedia article以獲得一個很好的介紹。

+0

但有些情況下,它是有道理的。例如,在代碼'Fruit * p = ...; Apple * q = dynamic_cast (p);如果(q){...使用q-> FindAppleWorm()...}。 –