Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

Probably what you want is something like:

struct vector_data
{
   union 
   {
        struct 
        {
            double x, y;
        }; 
        double data[2];
   }; 

   double& operator[](size_t index)
   {
       return data[index];
   }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top