问题描述
假设我有这些抽象类 Foo
和 Bar
:
Suppose I have these abstract classes Foo
and Bar
:
class Foo;
class Bar;
class Foo
{
public:
virtual Bar* bar() = 0;
};
class Bar
{
public:
virtual Foo* foo() = 0;
};
进一步假设我有派生类 ConcreteFoo
和 ConcreteBar
。我想协同改进 foo()
和 bar()
方法的返回类型,如下所示:
Suppose further that I have the derived class ConcreteFoo
and ConcreteBar
. I want to covariantly refine the return type of the foo()
and bar()
methods like this:
class ConcreteFoo : public Foo
{
public:
ConcreteBar* bar();
};
class ConcreteBar : public Bar
{
public:
ConcreteFoo* foo();
};
这不会编译,因为我们亲爱的单遍编译器不知道 ConcreteBar
将继承 Bar
,因此 ConcreteBar
是一个完全合法的协变返回类型。 Plain forward声明 ConcreteBar
也不工作,因为它不告诉编译器关于继承的任何事情。
This won't compile since our beloved single pass compiler does not know that ConcreteBar
will inherit from Bar
, and so that ConcreteBar
is a perfectly legal covariant return type. Plain forward declaring ConcreteBar
does not work, either, since it does not tell the compiler anything about inheritance.
这个C ++的许多缺点之一将不得不与这个困境一起生活或者真的有办法解决这个困境吗?
Is this one of the many shortcomings of C++ I'll have to live with or is there actually a way around this dilemma?
推荐答案
你可以很容易地伪造它,但是你失去了静态类型检查。如果你用 dynamic_casts
替换 static_casts
,你有编译器在内部使用的,但你没有动态或静态类型检查:
You can fake it quite easily, but you lose the static type checking. If you replace the dynamic_casts
by static_casts
, you have what the compiler is using internally, but you have no dynamic nor static type check:
class Foo;
class Bar;
class Foo
{
public:
Bar* bar();
protected:
virtual Bar* doBar();
};
class Bar;
{
public:
Foo* foo();
public:
virtual Foo* doFoo();
};
inline Bar* Foo::bar() { return doBar(); }
inline Foo* Bar::foo() { return doFoo(); }
class ConcreteFoo;
class ConcreteBar;
class ConcreteFoo : public Foo
{
public:
ConcreteBar* bar();
protected:
Bar* doBar();
};
class ConcreteBar : public Bar
{
public:
ConcreteFoo* foo();
public:
Foo* doFoo();
};
inline ConcreteBar* ConcreteFoo::bar() { return &dynamic_cast<ConcreteBar&>(*doBar()); }
inline ConcreteFoo* ConcreteBar::foo() { return &dynamic_cast<ConcreteFoo&>(*doFoo()); }
这篇关于有没有办法转发声明协方差?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!