C++ How to call a Child Method from Parent

Viewed 189

I'm working on a small project, and I found myself in a situation like this :

class A{}

class B : class A {
    public:
        void f();
        int getType() const;
    private:
        int type;
}

class C : class A{
    public:
        int getType() const;
    private:
        int type;
}

I want to know if there's a way to call the f() function (in class B) from an object of type A?

I tried this but it says function f() cannot be found in class A :

int main(){
    vector<A*> v;
    // v initialized with values of A ...
    if (v->getType() == 1){             // 1 is the type of B
        v->f();
    }
}
2 Answers

As you've seen, this code won't compile because A doesn't have an f method. In order to make it work, you'd have to explicitly downcast the pointer:

B* tmp = dynamic_cast<B*>(v);
tmp->f();

To begin with, with your current classes, you can't call getType() on an A*. Because the interface of A doesn't have this method. To solve this problem, you either need to make getType a virtual function in A, or move the type field to base class A (as protected) and initialize it in the constructors of the child classes. Let me show you the first method, because I think it is a better approach, since it makes the objective of this function more clear.

class A {
public:
  virtual int getType() { return 0; } // or delete the function: ... getType() = 0;
}

class B : public A {
public:
  int getType() override { return 1; }
}

With these classes, once you create an instance of B, getType() returns 1 when called on that instance, whether it is pointed to by an A* or B*:

A *object = new B();
object->getType(); // returns 1

Now, if you need to access the f() from B, you can again add it as a virtual method to A's interface, or make a cast to B*.

Using a virtual method:

class A {
public:
  virtual void f() { /* a default action maybe? */ }
}

class B : public A {
public:
  void f() /* override if you want */ { /* whatever this function does in B */ }
}

...

for (A *ptr : v)
  ptr->f();

Using a cast:

class A {
public:
  virtual int getType() { return 0; }
}

class B : public A {
public:
  void f();

  int getType() override { return 1; }
}

...

for (A *ptr : v)
  if (ptr->getType() == 1)
    dynamic_cast<B*>(ptr)->f();
Related