具有引用返回类型的重写方法上的协变返回类型无效

Invalid covariant return type on overridden methods with reference return types

本文关键字:返回类型 无效 重写 引用 方法      更新时间:2023-10-16

我正在使用 PIMPL 习语实现继承。我有两个类,例如:

// In Base.h
class Base
{
virtual BaseImpl& getImpl() const;
private:
std::unique_ptr<BaseImpl> _pImpl;
};
// In Derived.h
class Derived : public Base
{
DerivedImpl& getImpl() const /* override */;
};
// In BaseImpl.h
class BaseImpl { ... };
// In DerivedImpl.h
class DerivedImpl : public BaseImpl { ... };

现在,如果我取消注释上面的override关键字,编译器会抱怨协变返回类型在覆盖getImpl()时无效。

由于DerivedImpl派生自BaseImpl并且我返回引用,那么这里的协方差问题在哪里?

注意:此代码示例是自愿不排序的,类位于独立的文件中。问题仅与override关键字有关。代码在没有它的情况下编译。

由于 DerivedImpl 派生自 BaseImpl,而我返回引用,这里的协方差问题在哪里?

问题是编译器无法预测DerivedImpl是否会从BaseImpl派生。它还不知道这一点,因为在声明被覆盖的函数时尚未定义DerivedImpl。这可以通过重新排序定义来解决:

class BaseImpl {  };
class DerivedImpl : public BaseImpl {  };
class Derived : public Base
{
DerivedImpl& getImpl() const override ;
};

如果不能使返回类型的定义在函数声明点可见,则不能使用协变返回类型。