Изменение ссылок на константы

#c #reference #constants

Вопрос:

Предположим, у меня есть функция, которая возвращает ссылку на константу. Я не могу изменить эту функцию. Кроме того, у меня есть еще один класс под названием MyClass

 const Valueamp; GetValue(const MyClassamp; m, const unsigned long i) {  ....  val is assigned by using m amp; i  ...  return val; }  

Где — то еще в коде. Я должен реализовать другую функцию:

 void NewFunction(int r, int i) {  MyClass a = GetClass();  MyClass b = GetClass();  MyClass c = GetClass();   ...  Above a, b, and c are modified differently  ....   const Valueamp; cv;  if (r==1)  cv = GetValue(a,i);  else if (r==2)  cv = GetValue(b,i);  else  cv = GetValue(c,i);   ... }  

Сначала «Значение constamp; cv;» должно быть назначено при объявлении, но я не знаю, каким будет назначение при объявлении, пока я не пройду условное if-else. Второе «GetValue» возвращает константу, поэтому я не знаю, как с этим справиться, и смогу ли я безопасно изменить «cv» позже

Я не могу изменить шаблоны функций.

Нужно ли мне прибегать к указателям или есть другой элегантный способ справиться с этим?

Редактировать: Чтобы добавить сложности, Значение-это абстрактный класс, поэтому я не могу этого сделать

 Value cv;  

потому что компилятор справедливо жалуется, что «объект абстрактного класса не разрешен»

Комментарии:

1. Должно ли cv быть const?

2. Всякий раз, когда у меня есть переключатель с разрывами или цепочка if, которая присваивает значение, перемещение его в отдельную функцию почти всегда улучшало мой код.

3. «если я смогу безопасно изменить» резюме «позже» — измените cv так, чтобы оно указывало на другой объект (известный как «повторное заполнение»), или измените const объект, в котором GetValue() говорится, что вам запрещено изменять? Ссылка, поддерживающая повторную установку, называется «указателем». Нарушение GetValue() интерфейса почти наверняка является неопределенным поведением.

4. Присвоение имен переменным было моей ошибкой. Исправлено сейчас

5. @мтс Хорошо, хорошо. Разве ни один из ответов не отвечает на ваш вопрос? Я все еще удивляюсь, почему GetValue в нем нет функции-члена MyClass .

Ответ №1:

Хотя это не самое красивое, вы могли бы использовать вложенные троичные числа:

 const Valueamp; cv = (r == 1) ? GetValue(a, i)  : (r == 2) ? GetValue(b, i)  : GetValue(c, i)  

Вы также могли бы сделать что-то вроде:

 MyClass obj_to_pass; if (r==1)  obj_to_pass = a; else if (r==2)  obj_to_pass = b; else  obj_to_pass = c;   const Valueamp; cv = GetValue(obj_to_pass, i);  

Комментарии:

1. Троичное решение прекрасно, но другое копирует объект, который может быть проблемой.

Ответ №2:

 const Valueamp; NewFunctionHelper(int r, const unsigned long i, const MyClassamp; a, const MyClassamp; b, const MyClassamp; c) {  if (r==1)  return GetValue(a,i);  else if (r==2)  return GetValue(b,i);  else  return GetValue(c,i); }  

А затем в вашем обычном методе:

 Above a, b, and c are modified differently .... const Valueamp; cv = NewFunctionHelper(a, i, a, b, c);  

Всякий раз, когда у меня есть переключатель с разрывами или цепочка if, которая присваивает значение, перемещение его в отдельную функцию почти всегда улучшало мой код.