2017-07-27 69 views
1

比方說,我有一組以下類:如何從一組派生類創建列表?

class animal 
{ 
// members, constructors and other methods... 

public: 
    virtual void what_do_you_eat() { cout << "i eat generic food" << endl; } 
} 

class cat : public animal 
{ 
// members, constructors and other methods... 

public: 
    void what_do_you_eat() { cout << "i eat cat food" << endl; } 
} 

class dog : public animal 
{ 
// members, constructors and other methods... 

public: 
    void what_do_you_eat() { cout << "i eat dog food" << endl; } 
} 

,我想創建一個列表(任何容器就可以了,但我們選擇std::list<>在這個例子中):

std::list<animal> animals 
animals.push_back(dog()); 
animals.push_back(cat()); 

但當我嘗試遍歷列表我得到這樣的輸出:

for(auto itr : animals) 
{ 
    itr.what_do_you_eat(); 
} 
// output: 
// i eat generic food 
// i eat generic food 
// i eat generic food 
// i eat generic food 
// ... 

我試圖然後使指針列表(std::list<animal *> animals),輸出是正確的,但也有與此解決方案的許多問題:因爲標準說,STL容器不能容納一個const類型,我不能使用由animals舉行的std::list<animal * const> animals和指針列表

  • 可以覆蓋我的程序中的任何地方。
  • 我需要手動釋放它們。

問:
是否有可能通過一個派生類到一個STL容器,通過對基類的引用,仍然可以得到正確的輸出?

是否有任何解決方法可以在沒有指針的情況下正確執行此操作?目前,我正在編寫一個項目,這個項目很大程度上依賴於類的繼承,而我現在被卡住了,因爲我需要創建一個不同類型的對象列表(所有這些類型直接或間接從一個基類繼承)似乎是不可能的。

解決方案涉及boost庫是可以接受的。

回答

4

當你處理多態容器時,必須使用任何類型的指針。 最好使用智能指針,在你的情況下,std::unique_ptr將完美地完成這項工作。

因此,例如:

std::list<std::unieque_ptr<animal>> animals; 

animals.emplace_back(new dog {}); 
animals.emplace_back(new cat {}); 

注意基類animal必須有一個虛析構函數! 最好是將其定義爲一個抽象類:

class animal 
{ 
// NO members, NO constructors only pure virtual methods 
public: 
    virtual animal() {}; 
    virtual void what_do_you_eat() = 0; 
}; 
-1

在你的代碼,list<animal>list<animal*>,然後必須相應地改變代碼的其他行。

請參閱下面的代碼。它按預期工作。

class animal 
{ 
// members, constructors and other methods... 

public: 
      animal(){} 
    virtual ~animal(){} 

    virtual void what_do_you_eat() { cout << "i eat generic food" << endl; } 
}; 

class cat : public animal 
{ 
// members, constructors and other methods... 


public: 
      cat(){} 
    virtual ~cat(){} 

    void what_do_you_eat() { cout << "i eat cat food" << endl; } 
}; 

class dog : public animal 
{ 
// members, constructors and other methods... 

public: 
      dog(){} 
    virtual ~dog(){} 

    void what_do_you_eat() { cout << "i eat dog food" << endl; } 
}; 

int main() { 

    std::list<animal*> animals; 
    animal *a=new animal(); 
    dog *d=new dog(); 
    cat *c = new cat(); 

    animals.push_back(a); 
    animals.push_back(d); 
    animals.push_back(c); 

    for (std::list<animal*>::iterator itr=animals.begin(); itr!=animals.end(); ++itr) 
    { 

     (*itr)->what_do_you_eat(); 
    } 

    return 0; 
} 
+1

閱讀我的答案,並在代碼中找到至少2個錯誤。 –