Есть ли лучший способ инициализировать ссылочные члены, чтобы ссылаться на другого члена в том же классе

Прежде, чем кто-либо скажет что-либо, что я знаю, это, вероятно, не рекомендуется, но мне все еще любопытно, есть ли лучший способ сделать это или причины не выходить за рамки просто, это странная вещь, чтобы сделать.

Я начал изучать это, потому что я хотел получить доступ к элементам массива напрямую с семантически именованными членами в классе, в то же время имея возможность перебирать массив и не вызывать / создавать некоторые методы получения или установки.

У меня есть определение класса, которое выглядит примерно так.

class Vertex{
public:
Vertex(float x,float y,float z,float w);
float v[4];
float &x,&y,&Z,&w;
};

И конструктор, который выглядит следующим образом. Мой вопрос Есть ли лучший способ сделать то, что я делаю в конструкторе?

Vertex::Vertex(float vx,float vy,float vz,float vw):
x(*const_cast<float*>( &this->v[0] )),
y(*const_cast<float*>( &this->v[1] )),
z(*const_cast<float*>( &this->v[2] )),
w(*const_cast<float*>( &this->v[3] ))
{
v[0]=vx;
v[1]=vy;
v[2]=vz;
v[3]=vw;
}

РЕДАКТИРОВАТЬ

Я идиот … ты можешь просто сделать это, как сказал Джонатан Уэйкли.

x(v[0])

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

4

Решение

Vertex::Vertex(float vx,float vy,float vz,float vw):
v { vx, vy, vz, vw },
x(v[0]),
y(v[1]),
z(v[2]),
w(v[3])
{
}

Я бы не стал писать здесь референтных членов. Причина в том, что ссылочные элементы предотвращают использование по умолчанию (генерируется компилятором) специальных элементов копирования / назначения.

class Vertex{
public:
Vertex(float x,float y,float z,float w)
: v { x, y, z, w } { }

float &x() { return v[0]; }
float &y() { return v[1]; }
float &z() { return v[2]; }
float &w() { return v[3]; }

float const &x() const { return v[0]; }
float const &y() const { return v[1]; }
float const &z() const { return v[2]; }
float const &w() const { return v[3]; }
private:
float v[4];
};
7

Другие решения

Вы тоже можете пойти по этому пути:

class Vertex
{
public:
float x;
float y;
float z;
float w;

Vertex(float x, float y, float z, float w);

float&
operator[](int i)
{ return *(&x + i); }

float
operator[](int i) const
{ return *(&x + i); }
};

Возможно, этот вариант лучше (по сравнению с другими альтернативами), потому что он требует меньше кода и дает вам дополнительную возможность перебирать Vertex в стиле массива.

4

Лично мне больше всего нравится ответ @ sehe, но я дам вам альтернативу.

struct Vector4 {
float x;
float y;
float z;
float w;
};

union VectorUnion {
Vector4 vector;
float array[4];
};

Тогда вы можете просто использовать VectorUnion внутри вашего класса Vertex или самостоятельно …

Я обеспокоен тем фактом, что это конструкция C и структура C ++ немного отличается (она включает vtable и т. Д.), Но я думаю, что она должна работать.

Опять же, я думаю, что ответ @ sehe лучше.

2