我正在使用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
关键字有关。没有它的代码就会编译。
答案 0 :(得分:2)
由于DerivedImpl是从BaseImpl派生的,并且我返回了引用,所以这里的协方差问题在哪里?
问题是编译器无法预测DerivedImpl
是否会从BaseImpl
派生。它尚不知道,因为尚未在声明覆盖函数的位置定义DerivedImpl
。这可以通过重新排序定义来解决:
class BaseImpl { };
class DerivedImpl : public BaseImpl { };
class Derived : public Base
{
DerivedImpl& getImpl() const override ;
};
如果无法在函数的声明点使返回类型的定义可见,则不能使用协变返回类型。