覆盖子类中的返回类型

时间:2016-11-07 09:13:40

标签: c++ pointers inheritance polymorphism virtual

给定的是类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 个答案:

答案 0 :(得分:3)

您需要返回std::vector<std::shared_ptr<AbstractPrinter>>*。没有绕过它。您仍然可以通过ColorPrinter指针填充它。

协变返回类型允许您指定更多派生类型,作为虚函数的返回类型。但是vector的指针没有这样的关系。

另外,请考虑按值返回。借助NRVO和移动语义,向量非常善于有效地管理其资源。

答案 1 :(得分: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);
}

答案 2 :(得分: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 非虚拟(并按值返回)。