Динамическая память в С++

255
22 октября 2017, 22:26
Beverage * beverage2 = new DarkRoast();
beverage2 = new Whip(*beverage2);
delete beverage2;

Имеется абстрактный класс Beverage и его наследники: DarkRoast и Whip. При таком коде будет ли утечка памятью? И если да, то как правильнее переписать этот код так, чтобы не создавать лишнюю переменную, если вообще это реально. На java так получается довольно-таки легко.

Answer 1

Неизвестно.

Если есть конструктор Whip, принимающий ссылку, то утечки может не быть.

Whip(Beverage &p) : p(p) {};

В остальных случаях утечка есть, поскольку старое значение указателя beverage2 теряется.

Например, я могу дописать код так, что утечки не будет: https://ideone.com/lhxozT

#include <iostream>
using namespace std;
struct Beverage
{
  static int last;
  int i;
  Beverage() : i(++last) {}
  virtual ~Beverage() { cout << "~Beverage #" << i << endl;  }
};
int Beverage::last = 0;
struct DarkRoast : Beverage
{
  virtual ~DarkRoast() { cout << "~DarkRoast #" << i << endl; }
};
struct Whip : Beverage
{
  Beverage &p;
  Whip(Beverage &p) : p(p) {};
  virtual ~Whip() { cout << "~Whip #" << i << endl; delete &p; }
};
int main()
{
  Beverage * beverage2 = new DarkRoast();
  beverage2 = new Whip(*beverage2);
  delete beverage2;
  return 0;
}

Вывод:

~Whip #2
~DarkRoast #1
~Beverage #1
~Beverage #2
Answer 2

Будет. Потому что вы присваиваете новое значение, теряя старое - и больше не сможете ни обратиться к объекту класса DarkRoast, ни освободить занятую им память.

Здесь не Java, сборки мусора, к счастью, нет :)

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

READ ALSO
Как на основе массива составить другой массив с такой же суммой элементов?

Как на основе массива составить другой массив с такой же суммой элементов?

Дан исходный массив mas1Нужно заполнить новый массив mas2 так, чтобы выполнялись два условия:

289
Как обновить область уведомлений Windows?

Как обновить область уведомлений Windows?

Меняю в реестре флаг "EnableAutoTray" чтобы всегда выводились или скрывались значки в области уведомленийТолько одного изменения в реестре не достаточно,...

281
Не могу сделать перегрузку C++

Не могу сделать перегрузку C++

Не понимаю ошибку(((, надо сделать a[0] + a[2] - например, и чтобы в a[0] добавилась строка a[2];

282