Q:

A class ouput about C++ class

I have this code:
#include <iostream>
using namespace std;
class test {
public:
    int base;
    test() {
        base = 0;
    }
};
class deri : public test {
public:
    int der;
    deri() {
        der = 1;
    }
};
void foo(test* a, size_t size) {
    for (int i = 0; i != size; i++, a++) {
        cout << (*a).base << endl;;
    }
    cout << endl;
}
int main() {
//  test a[5];
    deri b[5];
//  foo(a, 5);
    foo(b, 5);
    return 0;
}

This outputs:
0
1
0
1

Why does the code output like in the comments?

A:

What foo thinks you're passing, an array of test instances:
      --------------------------
a --> |base|base|base|base|base|
      --------------------------

where each base is initialized to 0.
what you're actually passing, an array of deri instances:
      ----------------------------------------------
a --> |base,der|base,der|base,der|base,der|base,der|
      ----------------------------------------------

where each base is initialized to 0, and each der is initialized to 1.
When a is incremented, the function increments the memory address accounting for the stride of a test object (since that is the type of a), which has but-one member: base. In reality, the object's being passed are deri, and thus have two members: base and der. Thus after the first increment, you think you're doing this:
      --------------------------
      |base|base|base|base|base|
      --------------------------
    a -------^

but in reality you're doing this:
      ----------------------------------------------
      |base,der|base,der|base,der|base,der|base,der|
      ----------------------------------------------
   a -------^

and a, thinking it points to the second test, is actually pointing to the second member of the first deri object. A little instrumentation will show this. Printing the addresses of each member before we send the array to foo, then showing what we're actually doing in foo:
#include <iostream>
using namespace std;
class test {
public:
    int base;
    test() {
        base = 0;
    }
};

class deri : public test {
public:
    int der;
    deri() {
        der = 1;
    }
};
void foo(test* a, size_t size) {
    for (int i = 0; i != size; i++, a++) {
        cout << (const void*)&(*a).base << ',' << (*a).base << endl;;
    }
    cout << endl;
}
int main()
{
    deri b[5];
    for (auto const& x : b)
        std::cout <<(const void*)&x.base << ',' << (const void*)&x.der << '\n';

    foo(b, 5);
    return 0;
}

Output
0x7fff5fbff970,0x7fff5fbff974
0x7fff5fbff978,0x7fff5fbff97c
0x7fff5fbff980,0x7fff5fbff984
0x7fff5fbff988,0x7fff5fbff98c
0x7fff5fbff990,0x7fff5fbff994
0x7fff5fbff970,0
0x7fff5fbff974,1
0x7fff5fbff978,0
0x7fff5fbff97c,1
0x7fff5fbff980,0

Note the addresses will be system-dependent but hopefully you get the idea. In short, you have a bug.

