joaocandre
joaocandre

Reputation: 1745

Child class calls parent member instead of its own member

I'm trying to implement a couple of classes that share a lot of properties, by means of two classes that inherit certain members from a common parent class. In practice, what changes is how they handle a particular member, that would also be inherited, as it would be required from other members of the parent class:

#include <iostream>

class Parent{
public:
    Parent();
    Parent(const int _arg);
    ~Parent();
    int member1(const std::vector<float> _args);
    int member2(const std::vector<float> _args) { std::cout << shared(0.0) << std::endl;};
    int member3(const std::vector<float> _args);
    float shared(const float _val) {return 0.0;}; //dummy call in order for code to be compilable

protected:
    int protected_member1;
    int protected_member2;
    int protected_member3;
};

class Child1 : public Parent {
public:
    Child1(const int _arg):Parent(_arg);
    ~Child1();
    float shared(const float _val) {return 2.1;};
}

class Child2 : public Parent {
public:
    Child2(const int _arg):Parent(_arg);
    ~Child2();
    float shared(const float _val) {return 1.7;};
}

In practice, shared(const float _val) does more complex and problem-specific stuff, I tried to simplify the code in order to illustrate the issue more clearly (and removed irrelevant parts of the code as the definition of the remaining class members). However, when I call member2(const std::vector<float> _args) from each of the child classes, what is called is the base class member shared(const float _val) and not the child member.

int main(int argc, char const *argv[]){
    Parent p;
    Child1 c1;
    Child2 c2;

    c1.member2(std::vector<float> (5,1.0));
    c2.member2(std::vector<float> (5,1.0));

    return 0;
}

What am I doing wrong? Would a different approach to the problem make more sense?

Upvotes: 1

Views: 97

Answers (1)

Bathsheba
Bathsheba

Reputation: 234795

Polymorphism is not switched on by default in C++ (unlike Java for example). You need to mark shared virtual in the base class:

virtual float shared(const float _val) {return 0.0;}

If you never require a base class implementation, then you can make it pure virtual:

virtual float shared(const float _val) = 0;

Finally, in child classes, you can mark the function virtual too, although that has no effect. From C++11 onwards you can use the override keyword to the function which can improve the robustness of your program as withdrawing virtual from the base class will cause a compilation failure:

float shared(const float _val) override {return 2.1;}

Upvotes: 5

Related Questions