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?
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:
std::vector<deri> b(5)
and void f(const std::vector<deri> &vec)
.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).