Перегрузка оператора << нуждается в const; производит головную боль - PullRequest
1 голос
/ 21 февраля 2011

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

EDIT1: Код заглушки выглядит примерно так:

class Check

{   
public:
    void operator << (boost::any)
    {
        // checks weather the given is hresult,string(filename) or int(line no) 
        // and dump them into the exception object, 
        // There by hresult will initiate the object and int will throw the object.
        // so the input order must be like below
    }
private:
    Exception exception;
};

Использование

Check   check;
check << file->open << __FILE__ << __LINE__ ;

РЕДАКТИРОВАТЬ 2: Это для тех, кто когда-либо говорил, что синтаксис не подходит для реализации, я не хорошо опыт.программист.Я просто попытался сделать быстрое решение для исключения.Мой мотив - он не должен занимать больше времени, его легко набирать.Потому что мои коллеги должны использовать этот класс исключений.Я попытался найти решение для этого, и ответ пришел как << перегрузка оператора.Например, рассмотрим приведенный ниже пример </p>

1) Мой метод

#define INFO __LINE__ << __FILE__
c++
RunAndCheck runAndCheck;

try
{
    runAndCheck << checkVersion() << INFO;
    runAndCheck << file->Open() << INFO;
    runAndCheck << file->rename() << INFO;
}
catch(...)
{
}

2) Традиционный метод

#define INFO __FILE__,__LINE__
try
{
    runAndCheck.check(checkVersion(),INFO);
    runAndCheck.check(file->Open(),INFO);
    runAndCheck.check(file->rename(),INFO);
}
catch(...)
{
}

Может быть, в этой заглушке он будет более или менее одинаковым, но рассмотрим ситуацию, когда используется win32API.Там каждый звонок должен быть проверен на исключение.В этом случае я обнаружил, что << перегрузка легко набрать.Так что я сделал такой синтаксис </p>

Ответы [ 4 ]

7 голосов
/ 21 февраля 2011

operator<< не обязательно должна быть константной функцией.

Тем не менее, ваша реальная проблема - это тип возврата void.Чтобы связать вставки вместе, вам нужно вернуть *this.

5 голосов
/ 21 февраля 2011

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

  1. Ваш тип действует как встроенный тип (например, математический тип, массив или указатель), и вы хотите поддерживать встроенные операторы для вашего типа.
  2. Ваш тип должен поддерживать копирование, в этом случае вы должны реализовать operator =.
  3. Ваш тип должен взаимодействовать со стандартной библиотекой, такой как STL или потоки, в этом случае вам может потребоваться реализовать operator << для вставки потока или operator < для хранения вашего типа в стандартных классах контейнера.
  4. Вы хотите реализовать функциональный объект, в этом случае вы должны реализовать 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 любых перегруженных операторов, поэтому вы должны быть в порядке.

0 голосов
/ 21 февраля 2011

Вы реализуете operator<< как вставку в наш Check объект здесь. В этом случае, похоже, правильное решение состоит в том, чтобы просто вставить оператор вставки неконстантным, так как было бы бессмысленно использовать его для объекта const (потому что это мутирует состояние логического объекта).

0 голосов
/ 21 февраля 2011

Тогда вы, вероятно, делаете что-то не так. Опубликуйте соответствующие фрагменты своего кода вместе с более подробным описанием того, что вы пытаетесь сделать, и вы получите дополнительную помощь.

При этом, если вам нужно изменить некоторые данные в const-объекте, вы можете сделать пару вещей:

  1. Объявите участника, которого хотите изменить mutable.
  2. Используйте const_cast<...>(...) для удаления модификатора const из переданного объекта.

Но, скорее всего, вы пытаетесь сделать что-то не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...