2016-11-07 110 views
0

鑑於類IPrinterManager及其子類ColorPrinterManagerColorPrinterAbstractPrinter的子類。編輯中止消息ColorPrinterManager::print is not a covariant of IPrinterManager::print。我該如何解決這個問題?覆蓋子類中的返回類型

class IPrinterManager 
{ 
public: 

    virtual std::vector<std::shared_ptr<AbstractPrinter>>* print(std::string text) = 0; 

}; 

class ColorPrinterManager : public IPrinterManager 
{ 
public: 

    std::vector<std::shared_ptr<ColorPrinter>>* print(std::string text); 

}; 

回答

3

您需要退回std::vector<std::shared_ptr<AbstractPrinter>>*。它沒有四處走動。您仍然可以通過ColorPrinter指針填充它。

Covariant返回類型允許您指定更多派生類型作爲虛函數的返回類型。但指針的指針沒有這種關係。


此外,請考慮按價值返回。藉助NRVO和移動語義,矢量能夠有效地管理資源。

+0

但我想強制只能返回彩色打印機。有沒有其他方法可以做到這一點? – user1056903

+1

@ user1056903,你的實現是你如何執行的,客戶不應該在意。如果你想這樣做是因爲'AbstractPrinter'沒有提供足夠的界面來處理,你需要重新考慮你的設計。 – StoryTeller

0

ColorPrinter可能從AbstractPrinter衍生但shared_ptr<ColorPrinter>不是從shared_ptr<AbstractPrinter>衍生和vector<shared_ptr<ColorPrinter>>不是從vector<shared_ptr<AbstractPrinter>>的。所以你的print函數不是協變量。

您需要堅持使用vector<shared_ptr<AbstractPrinter>>。當然,如果你有一個像

ColorPrinterManager pm; 
auto v = pm.print(string("bla")); 
for(auto &s : v) { 
    // This gives you the AbstractPrinter 
    auto p = s.get(); 
    // If you called ColorPrinterManager you know that all printers are ColorPrinter 
    auto p2 = dynamic_cast<ColorPrinter*>(p); 
} 
0

代碼如果你真的需要協變返回類型在這裏,一個方法是定義打印機的容器旁邊的是打印機的並行層次結構,並用它來代替std::vector

// printers 
class AbstractPrinter { ... 

class ColourPrinter : public AbstractPrinter { ... 

// printer collections 
class AbstractPrinterCollection { 
     public: virtual AbstractPrinter* get(int i) = 0; ... 

class ColourPrinterCollection : public AbstractPrinterCollection { 
     public: ColourPrinter* get(int i) override { ... } 
     private: std::vector<std::shared_ptr<ColourPrinter>> vec; ... 

注1:get返回一個常規指針,而不是一個共享指針。這是因爲我們需要它具有協變返回類型,並且它不適用於智能指針。 (有辦法解決它)。注意2:整個層次結構中只有葉類具有數據成員(如具有實際打印機的實際容器),基類和中間類將數據委託給樹葉,並且可能是完全抽象的。

注3:AbstractPrinterCollection中沒有put(葉類中可能有put)。

注4:這很麻煩。考慮製作print非虛擬(並按值返回)。