Как добавить объединение членов в унаследованный класс / структуру - PullRequest
0 голосов
/ 15 февраля 2019
struct Foo 
{
    union {
        struct { int a, b; };
        int index[2];
    };
};

struct Bar : public Foo 
{
    union {
        // Foo members
        struct { int barA, barB; };
    };

};

int main()
{
    Foo f;
    Bar b;
    // I want it so that
    &b.a == &b.barA;
    // in the same way that
    &f.a == &f.index[0];
}

есть ли способ сделать так, чтобы члены Bar 'объединялись' с его родительским классом?

Большое спасибо, любая помощь очень ценится

edit: Вот пример использования согласно запросу:

struct Vec2
{
    union {
        float index[2]; 
        struct { float x, y; };
    };

    Vec2(float xVal, float yVal)
        : x(xVal), y(yVal)
    {   
    }

    ~Vec2() {}

    Vec2 & add(const Vec2 & b) { /* implimentation */ }
    Vec2 & sub(const Vec2 & b) { /* implimentation */ }

};

struct ComplexNumber : public Vec2
{
    union {
        // Vec2 members
        struct { float real, imag; };
    };

    ComplexNumber(float realPart, float imagPart)
        : real(realPart), imag(imagPart)
    {
    }

    ComplexNumber & mul(const ComplexNumber & b) { /* implimentation */ }
    ComplexNumber & div(const ComplexNumber & b) { /* implimentation */ }
};

int main()
{
    ComplexNumber a(5, 2);
    ComplexNumber b(7, 8);
}

Я хотел бы иметь возможность не только обращаться к членам Vec2 a и b, но также использовать функции, объявленные в Vec2 или, возможно,даже добавить ComplexNumbers и Vec2s взаимозаменяемо.

1 Ответ

0 голосов
/ 17 февраля 2019

Ваши союзы в Foo и в Bar являются анонимными.Это синтаксический сахар, который позволяет получить доступ к своим членам, как если бы они находились во включающем классе:

[class.union.anon] / 1: В целях поиска имени после определения анонимного объединения члены анонимного объединения считаются определенными в области, в которой объявлен анонимный союз.

Но это только облегчение доступа членов.Анонимный объект объединения не объединен с включенным классом.Как следствие, в Bar есть два разных объединения (с объектами по разным адресам).Они не могут быть объединены / объединены.

Кстати, стандарт прямо запрещает объединение наследовать любым способом:

[class.union] / 3: У союза не должно быть базовых классов.Союз не должен использоваться в качестве базового класса.

Невозможно сделать то, что вы собираетесь делать.

Глядя на ваш конкретный случай, объединенное объединение, которое вы хотели бы установить в производном классе, похоже, имеет отношение один к одному с частями базового класса.Ввиду этих обстоятельств вы могли бы в качестве обходного пути использовать несколько ссылок для ссылки на одного и того же члена:

struct ComplexNumber : public Vec2
{
    float &real=x, &imag=y;

    ComplexNumber(float realPart, float imagPart) : Vec2 (realPart, imagPart)
    {
    }
    ...
 }; 

Конечно, вам нужно реализовать правило 3,во избежание любой проблемы (например, ссылка указывает на неправильный объект, в случае, если сделан конструктор копирования или присваивание).

Теперь реальный вопрос в том, является ли комплекс Vec2.Лично я предпочел бы перейти к более ясному подходу, чтобы комплекс был независимым и имел класс Vec2.В этом случае комплекс переопределит операции Vec2 и перенаправит функции-члены члену Vec2.

...