首页 > 解决方案 > 在 C++ 中使用派生类型覆盖成员函数

问题描述

我的目标是使用rinB::g()作为 type Y

struct X {};
struct Y : X {};

struct A {
    virtual void f(X q);
    virtual void g(X& r);
    virtual void h(X* s);

    virtual X i();  // note: overridden function is 'virtual X A::i()'
    virtual X* j();
};

struct B final : A {
    void f(Y q) final;   // error: 'void B::f(Y)' marked 'final', but is not virtual
    void g(Y& r) final;  // error: 'void B::g(Y&)' marked 'final', but is not virtual
    void h(Y* s) final;  // error: 'void B::h(Y*)' marked 'final', but is not virtual

    Y i() final;   // error: invalid covariant return type for 'virtual Y B::i()'
    Y* j() final;  // works
};


标签: c++inheritanceoverridingoverloading

解决方案


您只能以一种仍然可以安全地使用派生类代替基类的方式覆盖虚函数(例如,通过指向基类的指针)。

让我们以您提供的类为例:

B b;
A *a = &b;

X x;
a->g(x);

在最后一行中,无法确保调用者按预期通过,g()因为调用者正在使用基类的接口,这通常是虚函数和动态多态性的重点。YB

另一方面,返回类型在派生类中更具体是安全的:

B b;
A *a = &b;
X *x = a->j();

即使j()实际返回,最后一条语句仍然是类型安全的Y*。这个 C++ 特性称为协变返回类型

您还可以在此处阅读有关类型系统中协变和逆变的更多信息。


推荐阅读