Множественное наследование и указатель this - PullRequest
3 голосов
/ 25 декабря 2011

Предположим, у меня есть такая структура:

struct vector_data
{
    double x, y;

    double& operator[](size_t index)
    {
        return * (static_cast<double*>(static_cast<void*>(this)) + index);
    }
};

Оператор [] должен работать как положено, потому что vector_data является типом POD. Ожидаемое поведение - vector_data [0] возвращает x, а vector_data [1] возвращает y.

Теперь предположим, что у меня есть вторая структура:

struct more_data
{
    double evil_data;

    // There could be more here, data or functions
};

И производные от обоих, как это:

struct composed : public more_data, public vector_data
{
};

Будет ли это разрушать ожидаемое поведение оператора []? Другими словами, будет ли указатель this вектора_data в производной структуре по-прежнему указывать на часть вектора vector_data структуры или он указывает на начало производной структуры?

Если он уничтожает оператор [], то как мне решить эту проблему? Сначала я могу унаследовать от vector_data, но предположим, что составленный содержит виртуальные функции. Я знаю, что большинство компиляторов ставят vtable в конце, но это не гарантируется. Какой будет лучший подход?

Ответы [ 2 ]

6 голосов
/ 25 декабря 2011

Оставляя в стороне проблемы неверной арифметики указателей (возможность дополнения между x и y делает ваше предположение недействительным), вот краткая иллюстрация того, что происходит с указателем this при использовании множественного наследования:

#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 и showB печать разных номеров;showC печатает тот же номер, что и showA, потому что a указан первым в списке баз.Если вы переключите a и b там, тогда showC и showB будут одинаковыми.«Волшебство» в компиляторе C ++: он достаточно умен, чтобы дать каждой функции-члену правильный указатель this.

1 голос
/ 25 декабря 2011

Вероятно, вы хотите что-то вроде:

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

   double& operator[](size_t index)
   {
       return data[index];
   }
}
...