Возврат константы из неконстантной функции - PullRequest
0 голосов
/ 26 марта 2020

У меня есть класс, в котором получение определенного члена по ссылке включает в себя лог c, поэтому я создал для него частную функцию получения, которая прекрасно работает внутри.

Я также хотел бы предоставить публичные c доступ к той же ссылке, но с постоянным модификатором. Поскольку функция publi c не должна изменять состояние класса, она объявляется с ключевым словом const. Однако внутренний лог c, так как он обеспечивает ссылку на внутренний элемент, не должен объявляться как const.

Как я могу использовать один и тот же лог c для получения ссылки и предоставить ей как постоянную, так и неконстантную точку доступа?

Есть ли здесь шаблон, который мне не хватает?

Ниже я собрал небольшой пример для демонстрации:

class my_class{
public:

  const int& get_my_field() const{
    return get_my_field_ref(); //g++: error: error - passing 'const my_class' as 'this' argument discards qualifiers [-fpermissive]
  }

private:
    int field;

    int& get_my_field_ref(){ //g++: warning: note - in call to 'int& my_class::get_my_field_ref()'
      /* ..complex logic to get reference.. */
      return field;
    }
};

Ответы [ 2 ]

0 голосов
/ 30 марта 2020

После обдумывания проблема в основном заключается в дизайне.

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

#include <iostream>

using namespace std;


class my_class{
public:

  const int& get_my_field() const{
    return field[complex_logic_to_get_reference()];
  }

private:
    int field[5];

    int complex_logic_to_get_reference() const{
      int result_index = 0;
      /* Complex logic to get reference */
      return result_index;
    }

    int& get_my_field_ref(int index){
      return field[complex_logic_to_get_reference()];
    }
};

int main(int argc, char *argv[])
{
    return 0;
}

Мои извинения @ j6t и @Peter за то, что я оставил эту информацию во время публикации вопроса, концепция действительно только что щелкнула.

0 голосов
/ 26 марта 2020

Некоторые люди Вы можете сделать это следующим образом, если вы знаете о предостережениях:

int& get_my_field_ref(){'
  /* ..complex logic to get reference.. */
  return field;
}
const int& get_my_field_ref() const {
  return const_cast<my_class&>(*this).get_my_field_ref();
}

Обратите внимание, что функция-член const более или менее гарантирует, что его можно использовать, не подвергаясь гонкам данных (он же является поточно-ориентированным). Вы должны реализовать свой complex logic, чтобы быть потокобезопасным.

Кроме того, убедитесь, что никогда не вызываете вашу функцию для объектов, которые были определены const. (const ссылки и указатели в порядке, если они прослеживаются до неконстантного объекта.)

...