C ++ Дочерняя структура с именами переменных, отличными от родительских - PullRequest
2 голосов
/ 19 марта 2020

Я создал трехмерный векторный класс, как этот

struct Vector3D {
    float x;
    float y;
    float z;

    Vector3D() {
        x = 0;
        y = 0;
        z = 0;
    }

    Vector3D(float x1,float y1,float z1=0) {
        x = x1;
        y = y1;
        z = z1;
    }

    //member functions for operator overloading, dot product, etc.
};

Но теперь я хочу сделать дочерний класс, заданный c для углов Эйлера. До сих пор у меня есть

struct Euler3D : Vector3D {
      float roll;
      float pitch;
      float yaw;
};

Как мне сделать класс так, чтобы угол наклона и рыскание ссылались на те же данные, что и x, y и z? Я думаю, что это включает union или что-то. Я хочу быть в состоянии достичь чего-то вроде этого:

Euler3D a = {1, 2, 3};
cout << a.x << endl; // prints 1
a.x = 1.5;
cout << a.roll << endl; //prints 1.5

Спасибо

Ответы [ 2 ]

2 голосов
/ 19 марта 2020

Как сделать так, чтобы уклон и наклон рычага ссылались на те же данные, что и x, y и z?

Вы не можете.

Так как вы хотите чтобы ссылаться на объект, вы могли бы использовать ссылку вместо этого, но это нарушает копирование - вы можете исправить конструктор копирования, используя определенный пользователем. Более того (как и ваше дублирование) это приводит к ненужным накладным расходам памяти.


Что вы можете сделать, это написать функцию, которая возвращает ссылку на член. как это:

struct Euler3D : Vector3D {
      float& roll() { return x; }

Но это тоже не идеально, потому что вам, вероятно, нужен как минимум второй набор перегрузок для const, так что много шаблонов.

Я думаю, что это включает union или что-то в этом роде.

Вы можете использовать union, чтобы иметь псевдонимов для членов, но тогда вы не сможете получить наследство. Это разрешено:

struct Euler3D {
    union { float x, roll;  };
    union { float y, pitch; };
    union { float z, yaw;   };
};

, который вы можете использовать точно так же, как в вашем фрагменте.

1 голос
/ 19 марта 2020

Как сделать так, чтобы уклон и наклон рычага ссылались на те же данные, что и x, y и z?

Подсказка в слове "reference" - вы можете сделать члены производного класса ссылками на соответствующие члены в базе.

РЕДАКТИРОВАТЬ: Как указано в комментариях, это также потребует от класса иметь конструктор копирования:

struct Euler3D : Vector3D {
    float& roll = Vector3D::x;   // You don't actually need the "Vector3D::" ...
    float& pitch = Vector3D::y;  // ... qualifiers here, but using them adds ...
    float& yaw = Vector3D::z;    // ... clarity for more complex cases.
    Euler3D() { }                // Should have def. ctor as we define the copy!
    Euler3D(const Euler3D& rhs) : Vector3D(rhs) { }
};

Вот небольшой фрагмент кода, иллюстрирующий, как это может работать:

int main()
{
    Euler3D* e3d = new Euler3D;
    e3d->roll = 1.1f;
    e3d->pitch = 2.2f;
    e3d->yaw = 3.3f;
    Vector3D* v3d = dynamic_cast<Vector3D*>(e3d);
    std::cout << v3d->x << " " << v3d->y << " " << v3d->z << std::endl;
    Euler3D e3d2 = *e3d;
    std::cout << e3d2.roll << " " << e3d2.pitch << " " << e3d2.yaw << std::endl;    // Copied from RHS
    e3d2.roll = 4.4f; e3d2.pitch = 5.5f; e3d2.yaw = 6.6f;
    std::cout << e3d2.roll << " " << e3d2.pitch << " " << e3d2.yaw << std::endl;    // Changed
    std::cout << v3d->x << " " << v3d->y << " " << v3d->z << std::endl;             // Not changed
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...