我有一个相当复杂的类层次在这类跨喜欢这取决于每个其他:有两个抽象的类和C包含一个方法,该方法返回的一个实例C和一个,分别。在他们继承的课程我想用一个共同变体类型,这是在这种情况下,一个问题,因为我不知道一种方法向前宣布继承有关的船舶。

我得到一个"测试。cpp:22:错误:无效的协变回归类于'虚拟D*B::outC()'"错误,因为编译器不知道这是一个子类。

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();
}

如果我改变返回型的B::outC()至C*例编译。是否有任何方式继续B*和D*作为回报类型的继承的课程(这将是直到我有一种方法)?

有帮助吗?

解决方案

我知道的任何方式的用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();
}

和用于所述第二

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();
}

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

其他提示

据我所知,没有办法做到这一点没有明确的铸造。问题是,定义类 B 不能知道 D 是一个子类的 C 直到看到一个全面的定义类 D, 但级的定义 D 不能知道 B 是一个子类的 A 直到看到一个全面的定义类 B, 等你有一个圆形的依赖。这不可能是解决与前向声明,因为一向宣言,不幸的是,无法指定一个继承关系。

有一个类似的问题在努力实施协变 clone() 方法的使用模板, 我找到可以解决, 但类似解决方案仍然失败,在这里,因为圆形的基准仍然是不可能解决。

您无法做到这一点,由于客户端的期望。当使用C实例,你不能告诉它是(A d或别的东西)的类C。因此,如果你存储在B指针(从派生类的调用产生的,但你没有在编译时知道)为指针,我不知道,所有的记忆的东西将是正确的。

当你调用一个方法上多态类型,运行时环境必须检查动态类型的对象,并将其移动指针,以满足你的类层次结构。我不知道,你应该依靠协方差。看看这个

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top