base class 指针,基于派生类型调用方法

base class pointer, invoke method based on derived type

我知道以下代码不起作用 -- 无法将 base 转换为 foo。

有什么我可以做的,或者可以采用某种模式来关闭我试图在下面的代码中实现的行为吗? IOW,如果我有一个指向派生类型的基 class 指针,我如何调用与派生类型(而不是基类型)匹配的特定方法?

我可以使用哪些模式?我研究了 Curiously Recursive (or recurring) Template Pattern,但是这本身就强加了其他限制。

class base {};
class foo : public base {};
void method(const foo& f){}
int main(){
  base* b = new foo();
  method(*b);
}

使用virtual函数解决这类问题:

class base {
  public:
    virtual void func() const { /* A */ }
};
class foo : public base {
  public:
    void func() const override { /* B */ }
};
void method(const base& f) {
    f.func();
}
int main(){
  base* b = new foo();
  method(*b);
}

现在,根据 f 的实际类型,AB 代码将在 method 中执行。

最简单的方法可能就是让 method() 成为 foo 上的 virtual 成员函数:

class base { 
 public:
  virtual void method() const = 0;
};
class foo : public base {
 public:
  void method() const override { }
};

int main(){
  foo f;
  base* b = &f;
  b->method();
}

但如果出于某种原因这是不可能的(也许您无权访问 method() 或者您希望将 method() 中的逻辑与 foo 分开)您可以使用 Visitor Pattern.

的简化版本

访问者模式依赖于层次结构中的所有 classes 具有基于 class 类型进行分派的虚函数。

在你的情况下你不需要双重调度所以你实际上不需要访问者对象并且可以直接从虚拟 dispatch 函数调用你的 method 函数:

class base { 
 public:
  virtual void dispatch() const = 0;
};
class foo : public base {
 public:
  void dispatch() const override;
};

void method(const foo& f){}

void foo::dispatch() const {
  method(*this);
}

int main(){
  foo f;
  base* b = &f;
  b->dispatch();
}

你必须记住,在大多数情况下,编译器不知道你的 base 指针实际上是 foo 类型。