Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better way to initialize reference members to reference another member in the same class

Before anyone says anything I know this is probably not recommended but I am still curious if there is a better way to do it or reasons not to beyond just it's a strange thing to do.

I started looking into this because I wanted to access elements of an array directly with semantically named members in the class while still being able to iterate over the array and not have to call/create some getter or setter methods.

I have a class definition that looks something like this.

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

And a constructor that looks like this. My question is. Is there a better way of doing what I am doing in the constructor?

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;
}

EDIT

I'm an idiot... you can just do it like Jonathan Wakely said.

x(v[0]) 

I guess I had some other problems before when I tried it. Oh well.

like image 336
Robert F. Avatar asked Dec 12 '22 16:12

Robert F.


2 Answers

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])
{
}

I'd avoid writing reference members here. The reason is that reference members prevent defaulted (compiler generated) copy/assignment special members.

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];
};
like image 66
sehe Avatar answered Apr 30 '23 23:04

sehe


You could go this way too:

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); }
};

Probably, this variant is better (compared to other alternatives) because it requires less code and gives you the additional ability to iterate over Vertex in array-style.

like image 21
Alexander Shukaev Avatar answered May 01 '23 01:05

Alexander Shukaev