重写子类中的返回类型
Overriding return type in child class
已知类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);
};
您需要返回std::vector<std::shared_ptr<AbstractPrinter>>*
。这是无可回避的。你仍然可以用ColorPrinter
指针填充它。
协变返回类型允许指定更派生的类型,作为虚函数的返回类型。但是指针的 vector
s没有这样的关系。
同样,考虑按值返回。有了NRVO和move语义,向量真的很擅长有效地管理它们的资源。
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);
}
如果您在这里确实需要协变返回类型,一种方法是在打印机容器的旁边定义一个并行的层次结构,并使用它来代替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
非虚拟(并按值返回)。
- 从父类方法返回子类对象
- C ++类型特征:确保子类实现方法
- 文本冒险游戏 - 如何区分一种项目类型与另一种项目类型以及如何构建项目类/子类
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 将成员函数的返回类型引用到C++中的自定义类
- 返回具体子类实例的 C++ 虚拟类函数
- 当函数返回类型为父类时,如何返回子类的对象?
- 如何使函数返回由子类定义的值?C++
- 为什么+运算符重载返回类型是类类型而不是整数
- 使用另一个类作为返回类型的类
- 非标量类型子类错误
- 当返回类型为类时,带有尾随返回类型的 GCC 属性警告
- 为什么编译没有错误?(返回不对所述返回类型进行子类化的类型)
- 返回类型是类中的一个变量
- 返回指向子类的指针的好方法
- 模板类的不同返回类型取决于类的形参
- 重写子类中的返回类型
- 如何返回“set”方法的子类类型
- 可以对返回子类类型的基类进行赋值操作符吗?
- 如何使子类上的操作符返回子类类型?