Suppose I have this struct:
struct vector_data
{
double x, y;
double& operator[](size_t index)
{
return * (static_cast<double*>(static_cast<void*>(this)) + index);
}
};
The operator[] should work as expected, because vector_data is a POD type. The expected behaviour is that vector_data[0] returns x, and vector_data[1] returns y.
Now suppose I have a second struct:
struct more_data
{
double evil_data;
// There could be more here, data or functions
};
And derive from both like this:
struct composed : public more_data, public vector_data
{
};
Will this destory the expected behaviour of operator[]? In other words, will the this-pointer of vector_data in the derived struct still point to the vector_data part of the struct, or will it point to the beginning of the derived struct?
If it does destroy operator[], then how can I resolve this problem? I can inherit from vector_data first, but suppose composed contains virtual functions. I know most compilers put the vtable at the end, but this is not guaranteed. What would be the best approach?
Leaving aside the issues of your incorrect pointer arithmetics (the possibility of padding between x
and y
invalidates your assumption), here is a quick illustration of what's going on with this
pointer when you use multiple inheritance:
#include <iostream>
using namespace std;
struct a {
int aa;
void showA() {
cerr << this << endl;
}
};
struct b {
int bb;
void showB() {
cerr << this << endl;
}
};
struct c : public a, b {
int cc;
void showC() {
cerr << this << endl;
}
};
int main() {
c x;
x.showA();
x.showB();
x.showC();
}
showA
and showB
print different numbers; showC
prints the same number as showA
, because a
is listed first in the list of bases. If you switch a
and b
there, then showC
and showB
would be the same. The "magic" is in the C++ compiler: it is smart enough to give each member function a correct this
pointer.