C++:如何在没有强制转换的情况下避免继承类中的"无效协变返回类型"?

Sea*_*les 13 c++ inheritance covariance

我有一个相当复杂的类层次结构,其中类是相互依赖的:有两个抽象类A和C,它们分别包含一个返回C和A实例的方法.在他们继承的类中,我想使用一个co-variant类型,在这种情况下是一个问题,因为我不知道一种方法来转发声明继承关系.

我得到一个"test.cpp:22:错误:'虚拟D*B :: outC()'的无效协变返回类型" - 错误,因为编译器不知道D是C的子类.

class C;

class A {
public:
        virtual C* outC() = 0;
};

class C {
public:
        virtual A* outA() = 0;
};


class D;

class B : public A {
public:
        D* outC();
};

class D : public C {
public:
        B* outA();
};

D* B::outC() {
        return new D();
}

B* D::outA() {
        return new B();
}
Run Code Online (Sandbox Code Playgroud)

如果我将B :: outC()的返回类型更改为C*,则示例将进行编译.有没有办法将B*和D*保留为继承类中的返回类型(对我来说,有一种方法可以直观)?

APr*_*mer 8

我知道在C++中无法直接耦合协变成员.您将要么添加图层,要么自己实现协变回报.

第一种选择

class C;

class A {
public:
        virtual C* outC() = 0;
};

class C {
public:
        virtual A* outA() = 0;
};


class BI : public A {
public:
};

class D : public C {
public:
        BI* outA();
};

class B: public BI {
public:
        D* outC();
};

D* B::outC() {
        return new D();
}

BI* D::outA() {
        return new B();
}
Run Code Online (Sandbox Code Playgroud)

而对于第二个

class C;

class A {
public:
        C* outC() { return do_outC(); }
        virtual C* do_outC() = 0;
};

class C {
public:
        virtual A* outA() = 0;
};


class D;

class B : public A {
public:
        D* outC();
        virtual C* do_outC();
};

class D : public C {
public:
        B* outA();
};

D* B::outC() {
        return static_cast<D*>(do_outC());
}

C* B::do_outC() {
        return new D();
}

B* D::outA() {
        return new B();
}
Run Code Online (Sandbox Code Playgroud)

请注意,这第二个选项是什么是由编译器隐式进行(有一些静态检查该的static_cast有效).