Операторы инкремента префикса/Постфикса

Я желаю удостовериться, что я понимаю передачу значением по сравнению с передачей ссылкой правильно. В частности, я смотрю на версии префикса/постфикса инкремента ++ оператор для объекта.

Давайте предположим, что у нас есть следующий класс X:

class X{
private:
    int i;
public:
 X(){i=0;}
 X& operator ++ (){ ++i; return *this; } //prefix increment

 X operator ++ (int unused){ //postfix increment
  X ret(*this);
  i++;
  return ret;
 }

 operator int(){ return i; } //int cast
};

В первую очередь, я реализовал операторы инкремента префикса/постфикса правильно?

Во-вторых, насколько эффективный памятью постфиксный оператор, по сравнению с префиксным оператором? Конкретно, сколько X объектные копии создаются, когда каждая версия оператора используется?

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


Править: Например, со следующим кодом...

X a;
X b=a++;

... a и b, теперь искажает?

21
задан Cam 5 July 2010 в 17:38
поделиться

3 ответа

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

При использовании return-by-reference вы возвращаете ссылку l-значения на текущий объект. Компилятор обычно реализует это путем возврата адреса текущего объекта. Это означает, что возврат объекта так же прост, как возврат числа.

Однако при возврате по значению необходимо выполнить копирование. Это означает, что во время возврата нужно скопировать больше информации (вместо простого адреса), а также вызвать конструктор копирования. Именно здесь и возникает удар по производительности.

Эффективность вашей реализации выглядит на уровне типичных реализаций.

РЕДАКТИРОВАНИЕ: Что касается вашего дополнения, нет, это не псевдонимы. Вы создали два отдельных объекта. Когда вы возвращаете по значению (и когда вы создали новый объект внутри оператора постфиксного инкремента), этот новый объект помещается в отдельную область памяти.

Однако в следующем коде a и b являются псевдонимами:

 int a = 0;
 int& b = ++a;

b - это адрес, который ссылается на a.

17
ответ дан 29 November 2019 в 20:43
поделиться

Более идиоматично вызывать префиксное приращение самого объекта в постфиксном приращении:

X operator++(int)
{
    X copy(*this);
    ++*this;         // call the prefix increment
    return copy;
}

Логика увеличения объекта X таким образом, содержится исключительно внутри префиксной версии.

20
ответ дан 29 November 2019 в 20:43
поделиться

Ваши операторы реализованы правильно.

В префиксном операторе копии X не создаются.

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

2
ответ дан 29 November 2019 в 20:43
поделиться
Другие вопросы по тегам:

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