Как я могу проиндексировать коллекцию и позволить каждой переменной индекса иметь свой собственный установщик? - PullRequest
0 голосов
/ 16 августа 2010

Итак, у меня есть объект с именем Vertex, который содержит некоторые параметры (давайте назовем их sx, sy и i).sx, sy и i каждый имеет специальные установщики: то есть Vertex выглядит примерно так:

class Vertex {
    public:
        float sx() { return sx; };

        void setSx(float val) {
            val > 0 ? sx = val : sx = 0;
        };

        float sy() { return sy; };

        void setSy(float val) {
            val >= 0 ? sx = val * 0.5 : sx = -val;
        };

        float i() { return i; };

        void setI(float val) { i = val; };

    private:
        float sx, sy, i;
};

Я бы хотел иметь возможность перебирать параметры Vertex безнеобходимость вызова каждого сеттера.Например:

Vertex* v = new Vertex();
for (int i = 0; i < Vertex::size; i++)
    (*v)[i] = 0;

или что-то в этом роде вместо необходимости использовать более грубую запись:

Vertex* v = new Vertex();
v->sx = 0;
v->sy = 0;
v->i = 0;

Есть ли способ сделать это более элегантным способом, чем просто перегрузкаoperator[] а используя оператор switch?Мне не нужно использовать точную нотацию, которую я продемонстрировал выше, мне просто нужен способ перебирать компоненты Vertex, не заботясь о пользовательских установщиках каждого из них.

Ответы [ 3 ]

3 голосов
/ 16 августа 2010

Кража у Джеймса Керрана (и незначительная адаптация):

(Джеймс, если вы хотите использовать этот метод, я его удалю).: -)

class Vertex {
  public:
    float sx() const        {return data[0];}
    float sy() const        {return data[1];}
    float i()  const        {return data[2];}

    void setSx(float val)   {data[0] = val >  0 ? val       : 0;   }
    void setSy(float val)   {data[1] = val >= 0 ? val * 0.5 : -val;}
    void setI(float val)    {data[2] = val;                        }

    float& operator[](int n)
    {
           return data[n];
    }

    float const& operator[](int n) const
    {
           return data[n];
    }

    static std::size_t size() {return 3;}

  private:
    float data[3];
};
2 голосов
/ 16 августа 2010

Как насчет метода сброса ().
Или просто сделайте это в конструкторе, чтобы при его создании объект был правильно инициализирован.

2 голосов
/ 16 августа 2010

Вы можете создать массив указателей для чисел с плавающей точкой и индексировать их, но я не уверен, будет ли результат квалифицирован как «самый элегантный»

class Vertex { 
      float* varptr[3];
    public: 
        Vertex ()
        {
              varptr[0] = &(this.sx);
              varptr[1] = &(this.sy);
              varptr[2] = &(this.i);
         }
         float& operator[](int n)
         {
               return *varptr[n];
         }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...