Причина, по которой у вас возникают проблемы, заключается в том, что это неуместное использование перегрузки оператора. Перегрузка оператора лучше всего используется в следующих местах:
- Ваш тип действует как встроенный тип (например, математический тип, массив или указатель), и вы хотите поддерживать встроенные операторы для вашего типа.
- Ваш тип должен поддерживать копирование, в этом случае вы должны реализовать
operator =
.
- Ваш тип должен взаимодействовать со стандартной библиотекой, такой как STL или потоки, в этом случае вам может потребоваться реализовать
operator <<
для вставки потока или operator <
для хранения вашего типа в стандартных классах контейнера.
- Вы хотите реализовать функциональный объект, в этом случае вы должны реализовать
operator ()
.
Код, который вы имеете выше, не попадает ни в одну из этих категорий, и, следовательно, любое его использование может запутать людей. Например, если кто-то не разбирается в вашем проекте, видит что-то вроде этого:
myCheck << myValue;
Они, вероятно, думают: «О, это какая-то вставка потока» или «О, это математический тип, сдвигаемый по битам». Однако в вашем случае этот код действительно означает «иметь объект проверки myCheck
validate myValue
». Если это то, что вы хотите сделать, то напишите что-нибудь более явное, например
myCheck.validate(myValue);
Теперь кто-то, просматривая ваш код, может лучше понять, как он работает и что он пытается сделать.
В общем, думайте о принципе наименьшего удивления при написании кода - код не должен удивлять вас тем, как он работает. Используя operator <<
в нестандартном контексте, вы, скорее всего, заставите программистов неправильно интерпретировать ваш код или понять, что он делает. Более четкое представление о ваших намерениях, используя именованные функции, а не перегруженные операторы в этом и связанных контекстах, делает код более читабельным и снижает вероятность того, что код будет сбивать людей с толку, читающих его.
Теперь что касается фактического ответа на ваш вопрос. Не требуется, чтобы operator <<
была const
функцией-членом. Подумайте о стандартных классах потоков, таких как cout
или ofstream
; операция
cout << "Hello, world!" << endl;
Определенно изменяет cout
, добавляя в него новые данные, так же, как операция
cout << setfill('0') << left << hex;
Изменяет cout
, изменяя флаги форматирования. Итак, если вы хотите, чтобы ваша функция operator <<
изменяла объект, в который помещаются данные, непременно сделайте это и сделайте ее функцией, не являющейся const
. C ++ не имеет никаких ожиданий относительно const
ness или не const
ness любых перегруженных операторов, поэтому вы должны быть в порядке.