0

I have the following classes in my program:

class base {
public:
    int bval;
    base() {
        bval = 1;
    }
};

class deri: public base {
    int dval;
public:
    deri() {
        dval = 2;
    }
};

And a function f that takes pointer to object of class base and size of array pointed by it:

void f(base *arr, int size) {
    for(int i=0; i<size; i++, arr++){
        cout << arr->bval << " ";
    }
    cout << endl;
}

This is the main:

int main() {
    base a[5];
    f(a, 5); // first call

    deri b[5];
    f(b, 5); // second call
}

The output for first call is 1 1 1 1 1, which is correct.

But the output for second call is 1 2 1 2 1, which is quite unexpected to me. It seems as if the value of dval is getting printed in place of bval for every second iteration of for loop within the function f.

Furthermore, if I include another private data member int dval2 in class deri, the output to second call is 1 2 65535 1 2 every time I execute it (so 65535 doesn't look like any random value).

Why is this behaviour exhibited by arrow operator?

3
  • You pass the pointer as a base pointer, so the pointer arithmetic does not fit your deri array. Commented May 18, 2020 at 8:05
  • Sorry I misread the question. I have edited my comment. I still suggest to use std::vector and let f() take a const std::vector<deri>&. Commented May 18, 2020 at 8:06
  • @ypnos I would appreciate it if you could explain the pointer arithmetic taking place as an answer. Commented May 18, 2020 at 8:08

1 Answer 1

4

You pass the pointer as a base pointer to f(), so the pointer arithmetic does not fit your deri array.

At this point: for(int i=0; i<size; i++, arr++), only the size of base is added to arr, because arr is a base pointer.

It does not matter in this case what type of objects are really stored; they are not looked at when increasing the pointer value.

Two options that would help:

  1. Use C++ containers. E.g. std::vector<deri> b(5) and void f(const std::vector<deri> &vec).
  2. Pass an array of pointers. In this case, when the pointer is accessed with arrow-operator, polymorphism can take place. Note that your base class needs a vtable, which you will obtain by defining and declaring a virtual destructor (the vtable is not needed to provide the expected output, but for several other reasons).
Sign up to request clarification or add additional context in comments.

3 Comments

So are the members accessed by pointer arithmetic behind the scenes, even though we specify a name?
The member access is not your problem, the loop is where it goes wrong!
@KashinathPatekar, Because Base* gets bound at compile time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.