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

base class pointer, invoke method based on derived type

本文关键字:派生 类型 调用 方法 指针 于派生 基类      更新时间:2023-10-16

我明白下面的代码不能工作——不能将base转换为foo。

是否有一些我能做的,或者一些模式来采用,这将使我接近的行为,我想在下面的代码中实现?那么,如果我有一个指向派生类型的基类指针,如何调用与派生类型(而不是基类型)匹配的特定方法呢?

我可以使用什么模式?我研究了奇怪的递归(或循环)模板模式,然而这本身也带来了其他限制。

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

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

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分开),你可以使用简化版本的访问者模式。

访问者模式依赖于层次结构中的所有类都有一个基于类类型的虚函数来分派。

在你的情况下,你不需要双重调度,所以你实际上不需要访问者对象,你可以直接从虚拟的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类型的。

使用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中执行。