Как C++ знает, что приращение ++ является префиксом или постфиксом при перегрузке оператора
Я понимаю, как сделать префиксные и постфиксные инкременты. В моем классе DoStuff у меня есть:
// Prefix; returns the incremented value
friend const DoStuff& operator++(DoStuff& a);
// Postfix: returns the incremented value
friend const DoStuff operator++(DoStuff& a, int);
и вне класса, у меня есть
const DoStuff& operator++(DoStuff& a){
a.num++;
return a;
}
const DoStuff operator++(DoStuff& a, int){
DoStuff before(a.num);
a.num++;
return before;
}
для префиксных и постфиксных инкрементов соответственно. Что я не понимаю, так это то, как C++ знает, что первое представлено ++a
и последний a++
, Насколько я могу судить, префикс инкремент ссылается на адрес &
и это как-то означает, что ++
Символ оператора должен стоять перед ним. Кроме того, я не слишком уверен, почему постфиксу нужен int
переменная.
1 ответ
Когда компилятор читает ваш исходный код, он может выяснить, использовали ли вы префикс или постфикс. Очень просто: либо ++
подходит до или после какого-либо объекта.
Затем компилятор сгенерирует код для вызова нужной функции. Но как называется эта функция? Люди, которые разработали C++, решили сделать имя функции для перегруженных операторов operator
сопровождаемый оператором вы перегружаете (++
, --
, =
и т. д.) operator*
, operator-
, так далее.
Но проблема сейчас в том, что префиксный и постфиксный операторы приращения именуются operator++
, Как вы различаете их? Когда вы сталкиваетесь ++var
а также var++
, компилятор генерирует код для вызова operator++
для них обоих, но вы не хотите этого, потому что теперь вы не можете различить определения между постфиксом и оператором приращения префикса.
Чтобы решить эту проблему, дизайнеры того же языка добавили фиктивный параметр, int
, Таким образом, компилятор может вызвать operator++(0)
, или же operator++(42)
(или любое другое число, которое вам нравится, это не важно. Это фиктивный параметр), когда он встречает постфикс ++
и просто operator++()
когда он встречает префикс. Параметр только для дифференциации.
В общем, это проблема языкового дизайна. Когда дело доходит до дизайнерских решений, естественно, должны быть и другие решения (например, называть их operator_preinc()
а также operator_postinc()
), но это то, что дизайнеры C++ решили использовать. У них могут быть свои причины, или они могут быть произвольно выбраны, потому что, возможно, все другие варианты весят примерно одинаково.