robotguy63
robotguy63

Reputation: 1

C++ calling a parent class function that uses an overriden function

So I was wondering if it is possible in C++ to call a parent class method that uses an overridden method without using the parent version of the overridden method. (I know this is unclear so I made an example!)

For example, below I would like to call class A's version of findPath() from an object of class B, while using the addPoint method that is defined by class B. Currently, if I call findPath() from an object of class B, it uses the addPoint method defined in class A.

Actual Output:

A.findPath(), path = {1,2,3,4,5,6,7,8,9,10)

B.findPath(), path = {1,2,3,4,5,6,7,8,9,10)

Desired Output:

A.findPath(), path = {1,2,3,4,5,6,7,8,9,10}

B.findPath(), path = {2,4,9,16,25,36,49,64,81,100}

class A 
{ 
public:
    vector<int> path;

    void addPoint(int num) {
        path.push_back(num);
    }

    vector<int> findPath() {
        for (int i = 0; i < 10; i++) {
            addPoint(i);
        }
    } 
};

class B : public A
{
public:
    void addPoint(int num) {
        path.push_back(num*num);
    }
};

At the moment, I am copying and pasting findPath into class B to get the desired output, but I feel like there should be an easier way. Thanks!

Upvotes: 0

Views: 437

Answers (2)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123566

It is possible. This is known as the Template Method Pattern. The name is a bit unfortunate, because it has nothing to do with C++ templates. A base class can implement something and derived classes only override the individual steps of the bigger "something".

For example:

struct Base {
     virtual void stepA() = 0;
     virtual void stepB() = 0;
     virtual void stepC() = 0;
     void do_something_complicated() {
          stepA();
          stepB();
          stepC();
     }
};

Derived classes only override the methods for the individual steps, while they are composed in the base class already.

In your example you forgot to declare addPoint as virtual, A should have a virtual destructor and using override is recommended to let the compiler help you in case of mistakes:

class A 
{ 
public:
    vector<int> path;

    virtual void addPoint(int num) {
        path.push_back(num);
    }

    vector<int> findPath() {                // () was missing
        for (int i = 0; i < 10; i++) {
            addPoint(i);
        }
        return path;                        // return was missing
    } 

    virtual ~A() = default;
};

class B : public A
{
public:
    void addPoint(int num) override {
        path.push_back(num*num);
    }
};

Upvotes: 1

Werner Henze
Werner Henze

Reputation: 16781

You need to use virtual in the base class. You should also add override in the derived class, compare the CppCoreGuidelines.

class A 
{ 
public:
    ...

    virtual void addPoint(int num) {
        path.push_back(num);
    }

    ...
};

class B : public A
{
public:
    void addPoint(int num) override {
        path.push_back(num*num);
    }
};

Upvotes: 2

Related Questions