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

Просто любопытный на том, почему параметрический усилитель должен быть константой в операционной перегрузке

CVector& CVector::operator= (const CVector& param)
{
  x=param.x;
  y=param.y;
  return *this;
}

разве Вы, возможно, не легко сделали чего-то вроде этого??

CVector& CVector::operator= (CVector& param) //no const
{
  x=param.x;
  y=param.y;
  return *this;
}

Не, когда что-то становится константой, это является неизменным для остатка от срока действия приложений?? Как это отличается по операционной перегрузке???

6
задан numerical25 1 June 2010 в 13:09
поделиться

7 ответов

Параметр const является постоянным во всей функции, использующей его, он не меняет свою константу вне его.

В этом случае вы хотите объявить константный аргумент, чтобы ваш оператор присваивания принимал как неконстантные, так и константные переменные; последний случай, в частности, включает результат выражений, который является временной константной переменной и которую вы обычно хотите поддерживать в присваиваниях.

3
ответ дан 8 December 2019 в 18:32
поделиться

Другой причиной является возможность преобразований. Например:

string s = "foo";
s = "bar";

Здесь реализация может выбрать только оператор присваивания, который принимает const ссылку на строку в качестве параметра, и зависеть от компилятора, использующего конструктор для создания временной строки из char * "bar". Это не будет работать, если параметр op= не является const, так как вы не можете связать временную ссылку с неконстантной.

0
ответ дан 8 December 2019 в 18:32
поделиться

Вам не нужен const:

@numerical25: Просто интересно, почему параметр должен быть const в перегрузке операций

Это не обязательно, но это хорошее дизайнерское решение.

См. стандарт C++ раздел 12.8-9:

Объявленное пользователем копирующее присваивание оператор X::operator= является нестатической нешаблонная функция-член класса X с ровно одним параметром типа X, X&, const X&, volatile X& или const volatile X&


Я думаю, что это хорошая идея:

Использование параметра const кажется мне логичным решением, поскольку вы хотите быть уверены, что другое значение не будет изменено.

Это говорит другим людям, использующим ваш класс, что вы не будете менять значение other, когда вы говорите что-то вроде: myObject = other;, и это принудительно обеспечивается, чтобы вы не могли случайно изменить other.

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


const применяется только к текущей ссылке, а не к объекту:

@numerical25: Разве когда что-то становится const, оно не становится неизменным до конца жизни приложения? Чем это отличается от перегрузки операций ???

Ссылка const - это просто ссылка, которая является const. Она не изменяет const-ность фактического объекта, который вы передаете.


Пример перегрузки оператора без const:

Вот пример перегрузки оператора, где параметр не является const.

class B
{
public: 
 const B& operator=(B& other)
 {
  other.x = 3;
  x = other.x;
  return *this;
 }

 int x;
};


void main(int argc, char** argv[])
{
 B a;
 a.x = 33;
 B b;
 b.x = 44;
 a = b;//both a and b will be changed
 return 0;
}
8
ответ дан 8 December 2019 в 18:32
поделиться

Если вы использовали

CVector& CVector::operator= (CVector& param) // no const

, то сделали следующее:

const CVector& my_vector = GetMyVector();
some_other_vector = my_vector; // call assignment operator - error!

Вы получите сообщение об ошибке, потому что my_vector - это const CVector & , и это может Не приводятся к CVector и (неконстантная ссылка). Это просто локальная ссылка на него внутри функции operator = , которая является константой, а не сам объект целиком.

1
ответ дан 8 December 2019 в 18:32
поделиться

Вы можете использовать неконстантную разновидность, но это имеет два последствия: одно - функциональное, а второе - о том, что вы как автор функции сообщаете пользователю.

1) люди, вызывающие функцию, которая принимает неконстантную ссылку, не смогут вызвать ее с помощью константной переменной

2) когда у вас есть аргумент функции, который не является константной ссылкой, вы сигнализируете, «Я оставляю за собой право изменить это». Обычно, когда пользователь вашей функции пишет a = b ;, он не ожидает, что b изменится.

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

CVector& CVector::operator= (CVector param) //no reference

Здесь нет ни одной из проблем, о которых я упоминал выше. Однако это очень неэффективно. Из-за этих трех факторов предпочтительна передача по ссылке на константу, особенно в таких случаях, как вектор, где копирование может быть дорогостоящим.

1
ответ дан 8 December 2019 в 18:32
поделиться

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

0
ответ дан 8 December 2019 в 18:32
поделиться

Квалификатор const делает переданный параметр (в вашем примере это 'const CVector & param') только для чтения. Квалификатор const гарантирует, что параметр (param) не будет изменен внутри метода operator = ().

Без квалификатора const возможно следующее:

CVector& CVector::operator= (CVector& param)
{
  x=param.x;
  y=param.y;

  param.x = 10; // some random value
  param.y = 100;

  return *this;
}

Вышеупомянутый метод изменяет правый операнд 'param' после присвоения значения левому операнду. Квалификатор const помогает не нарушать семантику операции присваивания.

0
ответ дан 8 December 2019 в 18:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: