如何返回“set”方法的子类类型

How to return subclass type for a `set` method?

本文关键字:方法 子类 类型 set 何返回 返回      更新时间:2023-10-16

我想有一个类,其中集合返回this,所以我可以做嵌套集合。但是我的问题是,子类也会有一些集合,但如果API的用户首先从超类调用集合,类型改变,我不能调用子类方法。

class SuperA {
 public:
  SuperA* setValue(int x) {
    return this;
  }
}
class SubA : public SuperA {
 public:
  SubA* setOtherValue(int y) {
    return this;
  }
}
SubA* a = new SubA();
a->setValue(1)->setOtherValue(12); // Compile error

我该如何解决这个问题?由于

我觉得这听起来像是…奇怪的循环模板模式(CRTP)!

template <typename Child>
class SuperA
{
public:
    Child* setValue(int x)
    {
        //...
        return static_cast<Child*>(this);
    }
};
class SubA : public SuperA<SubA>
{
public:
    SubA* setOtherValue(int y)
    {
        //...
        return this;
    }
};

SubA* a = new SubA();
a->setValue(1)->setOtherValue(12); // Works!

搜索条件是协变返回类型

你必须在子类中重新定义setValue:例如

class SubA : public SuperA
{
public:
    SubA *setValue(int x) { SuperA::setValue(x); return this; }
    // other methods...
};

在这个例子中,setValue是非虚拟的,SubA::setValue隐藏了基类版本,它不覆盖。

如果函数是虚函数,那么只要子类版本的返回类型是指向超类版本返回类型的指针或引用,就仍然有效,并且会发生重写。