2

Есть ли способ изменить этот код, чтобы я не получал предупреждение при компиляции? Кроме того, не мог ли этот код потенциально привести к segfault, так как память, которую он собирается получить, чтобы получить значение x в main, была освобождена в конце вызова функции оператора?Как правильно перегрузить постфиксный оператор приращения?

class A { 

    int x; /* value to be post-incremented */ 

    public: 

    A() { /* default constructor */ 
    } 

    A(A & toCopy) { /* copy constructor */ 
    x = toCopy.x; 
    } 

    A & operator++(int) { /* returns a reference to A */ 

    A copy(*this);   /* allocate a copy on the stack */ 
    ++x; 

    return copy;   /* PROBLEM: returning copy results in a warning */ 

    }       /* memory for copy gets deallocated */ 

}; /* end of class A */ 

int main() { 

    A object; 
    object.x = 5; 

    cout << (object++).x << endl; /* Possible segfault ? */ 

} 
+2

Просто не возвращайте по ссылке. Вернитесь по значению, создав еще одну копию. –

ответ

6

Вы должны возвращать значение (не ссылка):

A operator++(int) { /*...*/ } 

это разрешит предупреждение компилятора и вы не будете в конечном итоге с висячей ссылкой.

+0

Омг это было так просто. Благодарю. Я приму ответ, как только это позволит. – Kacy

+0

Можете ли вы объяснить одну вещь? Какова ценность копии? Как то, что именно я возвращаю, что делает (объект ++) .x возможным? – Kacy

+0

@KacyRaye Вы возвращаете копию значения, как было до того, как вы ее модифицировали. Объект orignal модифицируется («объект» в вашем примере). Это возвращаемое значение называется временным (типа 'A'), и, следовательно, вы можете получить доступ к временным членам, добавив' .x'. –

2

Оператор постфикса не возвращает ссылки, возвращается по значению:

A operator++(int) { /* returns a copy */ 

    A copy(*this);   /* allocate a copy on the stack */ 
    ++x; 

    return copy; 

    } 

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

Также обратите внимание, что копия возврата может быть легко удалена компилятором через NRVO (этот код довольно хорош NRVO-friendly).

Смежные вопросы