2016-11-07 112 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非虚拟(并按值返回)。