деструктор работает раньше. Как? - PullRequest
4 голосов
/ 22 августа 2011
#include<iostream>

using namespace std;
class test
{
int a;
public:
test()
{
    a=0;
}
test operator ++(int)
{        a++;
    return *this;
}
void display()
{
    cout<<a;
}
~test() {
    cout << "DES" << endl;
}
  };
int main()
{
    test t,t1;
    t1 = t++;
    t.display();
    system("pause");
}

Вывод, который я получаю:

DES
1Press any key to continue...
DES 
DES

Почему деструктор работает раньше?

Ответы [ 6 ]

8 голосов
/ 22 августа 2011

Выражение t++ приводит к временному объекту типа test, поскольку operator++(int) возвращает значение [*]. Вы видите уничтожение этого временного объекта после того, как operator= завершит его использование для присвоения нового значения t1.

[*] Обычно это должно содержать значение t до его приращения, но в вашей реализации это просто копия объекта после приращения, которую вы создаете, выполняя return *this;. Таким образом, ваше тело функции больше подходит для operator++() (до приращения), чем operator++(int) (после приращения).

5 голосов
/ 22 августа 2011

Поскольку

t1 = t++;

создает временный объект, который будет уничтожен в конце выражения (;).

4 голосов
/ 22 августа 2011

Когда вы используете t++, создается временный объект. По этой причине у вас есть 3 деструктора, вызванные для 2 переменных. Если вы используете ++t, временный объект не будет создан. Что, кроме приоритета оператора, является основным отличием до и после увеличения.

1 голос
/ 22 августа 2011

Если вы хотите, чтобы ++ вел себя так же, как и для встроенных типов, то:

  • preincrement (++t) должен увеличиваться, а затем возвращать новое значение (которое может быть возвращено по ссылке);
  • postincrement (t++) должен скопировать исходное значение и вернуть его после увеличения.

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

Более каноническая реализация будет выглядеть так:

test & operator++() {
    ++a;
    return *this;
}
test operator++(int) {
    test copy = *this;
    ++a;
    return copy;
}
1 голос
/ 22 августа 2011

operator ++(int) возвращается по значению, а не по ссылке. временный создается и уничтожается.

1 голос
/ 22 августа 2011

Причина

test operator ++(int)
{
    a++;
    return *this;
}

возвращает временный объект, который уничтожается сразу один раз

t1 = t++;

выполняется, что происходит до вызова system().

...