c++ 虚函数中的协变返回类型的意义是什么?

lbsnaicq  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(121)

我见过的协变返回类型最常见的用法是通过虚函数。我能想到的最简单的例子看起来像这样:

class Base {
public:
  virtual Base& get() { return *this; }
};

class Derived : public Base {
public:
  Derived& get() override { return *this; }
};

有一件事我真的不明白,为什么要把这些功能虚拟化。get函数的返回类型是在调用点静态定义的,即使*this可以向下转换为Derived,我们也无法通过调用Base::get来获得Derived&。这一切都意味着多态性无论如何都不适用于返回类型。对我来说,让这些函数成为非虚函数,让基方法由子方法重新定义,看起来更合理一些。但人们还是喜欢把它们虚拟化,至少我注意到了。对此有什么解释吗?

ljsrvy3e

ljsrvy3e1#

使用更有用的示例clone

class Base {
public:
  virtual ~Base() = default;
  virtual Base* clone() const { return new Base(*this); }
  virtual void print() const { std::cout << "Base\n"; }
};

class Derived : public Base {
public:
  Derived* clone()  const override { return new Derived(*this); }
  void print() const override { std::cout << "Derived\n"; }
  void foo();
};

现在随着

void clone_and_print(const Base& base)
{
    auto p = base.clone(); // auto is Base*, dynamic type is the same as the one of base
    p->print(); // print Base or Derived
    delete p;
}

一切都很好。按照您的建议删除virtual会改变行为,并无条件地打印Base。
现在,一个协变返回类型有用的情况:

void clone_and_foo(const Derived& derived)
{
    auto p = derived.clone(); // auto is Derived*, not Base*
    p->foo(); // Won't work without covariant return type. would require a cast
    delete p;
}

相关问题