0

I am learning C++ and faced this quiz test. Why the output is always 1? Why the polymorphism is not working? The methods calculate os classes MyClassTwo and MyClassThree are not called.

#include <iostream>
using namespace std;
class MyClassOne {
public:
    int calculate() { return 1; }
};
class MyClassTwo : public MyClassOne {
public:
    virtual int calculate() { return 2; }
};
class MyClassThree : public MyClassTwo {
public:
    int calculate() { return 3; }
};
int main() {
    int result = 0;
    MyClassOne* objs[3];
    objs[0] = new MyClassOne();
    objs[1] = new MyClassTwo();
    objs[2] = new MyClassThree();
    for (int i = 0; i < 3; ++i) {
        cout << objs[i]->calculate() << endl;
    }
    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 2
    Make `calculate` virtual in the base class `MyClassOne`. – Daniel Langr Dec 04 '20 at 15:47
  • 1
    the baseclass doesn't have the `calculate` function virtual.... – JHBonarius Dec 04 '20 at 15:48
  • Instead of `virtual int calculate() { return 2; }` you should have `int calculate() override { return 2; }` and make the base function `virtual int calculate() { return 1; }`. Using `override` in the derived class will help you from making this mistake and other mistakes like having different signatures. – drescherjm Dec 04 '20 at 15:50
  • @drescherjm its a quiz test, so not a typo but on purpose. – 463035818_is_not_an_ai Dec 04 '20 at 15:52
  • You are correct. I was not the one that voted to close as a typo but thought of it. I did not read the question yet. I usually do a review of the code before looking at the question. – drescherjm Dec 04 '20 at 15:52
  • @drescherjm same here and I was too hastily with voting as typo. Btw not proud of the answer either, its not more than a spoiler of the quiz – 463035818_is_not_an_ai Dec 04 '20 at 15:59

2 Answers2

2

MyClassOne::calculate is not virtual:

class MyClassOne {
public:
    int calculate() { return 1; }
};

Hence, if you call calculate on a MyClassOne* what is called is that method, not something else.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
2

The static type of elements of the array objs is MyClassOne*

MyClassOne* objs[3];

So in this expression:

objs[i]->calculate()

The name calculate is searched in the class MyClassOne. In this class there is a declared non-virtual function calculate:

class MyClassOne {
public:
    int calculate() { return 1; }
};

That is called for each pointed object. Maybe you mean

class MyClassOne {
public:
    virtual int calculate() { return 1; }
};
Hegaja
  • 83
  • 1
  • 1
  • 6
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335