Прежде, чем кто-либо скажет что-либо, что я знаю, это, вероятно, не рекомендуется, но мне все еще любопытно, есть ли лучший способ сделать это или причины не выходить за рамки просто, это странная вещь, чтобы сделать.
Я начал изучать это, потому что я хотел получить доступ к элементам массива напрямую с семантически именованными членами в классе, в то же время имея возможность перебирать массив и не вызывать / создавать некоторые методы получения или установки.
У меня есть определение класса, которое выглядит примерно так.
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])
Я думаю, у меня были некоторые другие проблемы раньше, когда я попробовал это. Ну что ж.
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];
};
Вы тоже можете пойти по этому пути:
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
в стиле массива.
Лично мне больше всего нравится ответ @ sehe, но я дам вам альтернативу.
struct Vector4 {
float x;
float y;
float z;
float w;
};
union VectorUnion {
Vector4 vector;
float array[4];
};
Тогда вы можете просто использовать VectorUnion
внутри вашего класса Vertex или самостоятельно …
Я обеспокоен тем фактом, что это конструкция C и структура C ++ немного отличается (она включает vtable и т. Д.), Но я думаю, что она должна работать.
Опять же, я думаю, что ответ @ sehe лучше.