有没有办法转发声明协方差?

2024-01-29

假设我有这些抽象类Foo and Bar:

class Foo;
class Bar;

class Foo
{
public:
  virtual Bar* bar() = 0;
};

class Bar
{
public:
  virtual Foo* foo() = 0;
};

进一步假设我有派生类ConcreteFoo and ConcreteBar。我想协变地改进返回类型foo() and bar()像这样的方法:

class ConcreteFoo : public Foo
{
public:
  ConcreteBar* bar();
};

class ConcreteBar : public Bar
{
public:
  ConcreteFoo* foo();
};

这不会编译,因为我们心爱的单通道编译器不知道ConcreteBar将继承自Bar,所以ConcreteBar是一个完全合法的协变返回类型。简单的转发声明ConcreteBar也不起作用,因为它不会告诉编译器有关继承的任何信息。

这是我必须忍受的 C++ 的缺点吗?或者实际上有办法解决这个困境吗?


你可以很容易地伪造它,但你会失去静态类型检查。如果您更换dynamic_casts by static_casts,您拥有编译器在内部使用的内容,但没有动态或静态类型检查:

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()); }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有办法转发声明协方差? 的相关文章

随机推荐