简体   繁体   中英

base class pointer, invoke method based on derived type

I understand that the following code doesn't work -- can't convert base to foo.

Is there something I can do, or some pattern to employ which would get me close the behavior I'm trying to achieve in the code below? IOW, if I have a base class pointer to a derived type, how can I invoke a specific method that matches the derived type (not the base type)?

What patterns might I use? I looked into Curiously Recursive (or recurring) Template Pattern, however this imposed other limitations itself.

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

The easiest way is probably to just make method() a virtual member function on foo :

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();
}

But if for some reason that is not possible (perhaps you don't have access to method() or perhaps you want to keep the logic in method() separate from foo ) you could use a simplified version of the Visitor Pattern .

The visitor pattern relies on all the classes in your hierarchy having a virtual function to dispatch based on class type.

In your case you don't need double-dispatch so you don't actually need the visitor object and can just call your method function directly from a virtual dispatch function:

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();
}

You have to remember that in most contexts the compiler doesn't know that your base pointer is actually of type foo .

Use virtual functions to solve these kinds of problems:

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);
}

Now, depending on the actual type of f , either A or B code will be executed in method .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM