给定的是类IPrinterManager
及其子类ColorPrinterManager
。 ColorPrinter
是AbstractPrinter
的子类。编译以消息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);
};
答案 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
非虚拟(并按值返回)。