Разрушение деструкторов в Dev-C ++ и Code :: Blocks

#include <iostream>
using namespace std;

class Exem {
int *a;

public:
Exem() { a = new int; *a = 0; };
Exem (int x) { a = new int; *a = x; };

~Exem () { delete a; };

int f (void);

Exem operator+ (Exem);
};

int Exem::f (void) {
return *a * 2;
}

Exem Exem::operator+ (Exem nimda) {
Exem aux;

*aux.a = *a + *nimda.a;

return aux;
}

int main() {
Exem adabo(1);
Exem inakos(2);

adabo = adabo + inakos;

cout << adabo.f();
cin.get();
}

Это мой код, пример класса, созданный для демонстрации проблемы. Вывод main () теоретически будет равен «6», но все, что на самом деле появляется, это бессмысленные числа.

По-видимому, это связано с деструктором класса, который, как я понял, вызывается слишком рано в конце функции operator + — aux теряется до того, как его фактически пропустят. Я пришел к такому выводу, потому что ~ Exem (), когда он прокомментирован, позволяет программе работать так, как ожидалось.

Я предполагаю, что это связано с этими двумя компиляторами, потому что, когда я попытался скомпилировать точно такой же код в Embarcadero RAD Studio, это сработало бы.

2

Решение

Вам нужно явно определить конструктор копирования и оператор присваивания для Exem так как у вас есть динамически распределяемая переменная-член.

Если конструктор копирования и оператор присваивания не определены явно для класса, компилятор генерирует их версии по умолчанию, которые не подходят для класса, который имеет динамически размещаемые члены. Причиной того, что созданные по умолчанию версии являются неподходящими, является то, что они выполняют поверхностную копию элементов. В случае Exemкогда экземпляр этого копируется более чем один экземпляр Exem указывает на тот же динамически распределяемый int член по имени a, Когда один из экземпляров уничтожен, a deleted и оставляет другой экземпляр с висящим указателем и неопределенным поведением.

Увидеть правило трех.

Простое исправление для Exem будет меняться a из int* для int, Конструктор копирования по умолчанию, оператор присваивания и деструктор будут правильными.


Обратите внимание, что Exem::operator+() должен взять const Exem& параметр, поскольку он не меняет свой аргумент.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]