我有以下情况:
我指定一个纯虚函数:
virtual PredictedMatch PredictMatch(const Match &match) const = 0;
我也有:
class ImpactPredictedMatch : public PredictedMatch
现在,我想做:
ImpactPredictedMatch PredictMatch(const Match &match) const;
在一个实现前面的纯虚函数的类中。我假设编译器会根据需要简单地转换返回的类型,但我得到:
impact_predictor.h:18:24: error: invalid covariant return type for ‘virtual ImpactPredictedMatch ImpactPredictor::PredictMatch(const Match&) const’
ImpactPredictedMatch PredictMatch(const Match &match) const;
我接受这只是在C ++中不起作用,但我真的希望你建议最好做什么。我必须返回指针吗?我真的不愿意,因为我喜欢自动内存管理,但这是唯一的方法吗?
感谢您的帮助!
答案 0 :(得分:4)
当您返回更多派生类的实例时,调用代码可以期望存储在基类型的变量中。这样做的结果可能是切片,丢失数据并可能泄漏内存(最多)。如果需要协变返回类型,则唯一的选择是指针或引用类型。在这两种情况下,您都需要确保对象至少与指针/引用一样长。
答案 1 :(得分:1)
正如previous answer中所述,返回类型的协方差仅适用于指针或引用。
但是,您可以尝试使用name hidding模拟返回类型与值类型的协方差:
class Base {
public:
// Non-virtual, simply delegates to the protected virtual method.
// May be hidden in derived class in order to covariate the return type.
PredictedMatch predictMatch(const Match &match) const {
return this->doPredictMatch(match);
}
protected:
virtual PredictedMatch doPredictMatch(const Match &match) const = 0;
};
class Derived : public Base {
public:
// Hides Base::predictMatch()
ImpactPredictedMatch predictMatch(const Match &match) const;
private:
// Delegates to the specialized non-virtual member above
PredictedMatch doPredictMatch(const Match &match) const {
return this->predictMatch(match); // Slices the object
}
};
隐藏会员通常不被视为良好做法或推荐的设计工具。根据您想要实现的特定类设计,它可能会或可能不会更好地通过指针或引用返回。
我使用名称隐藏的一种情况就像上面的例子一样,实现了一个多态的clone()
方法,返回一个std::unique_ptr
(而不是返回一个原始指针,并希望用户记得读取方法的文档和正确管理对象的生命周期)。
另请注意,此设计使用"值协方差"假定您可以安全地转换或切片返回的对象而不改变含义。如果情况并非如此,那么我相信按价值或参考价格返回是您唯一的选择。