Страницы

Поиск по вопросам

пятница, 31 января 2020 г.

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

#cpp


Beverage * beverage2 = new DarkRoast();
beverage2 = new Whip(*beverage2);

delete beverage2;


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


Ответы

Ответ 1



Неизвестно. Если есть конструктор Whip, принимающий ссылку, то утечки может не быть. Whip(Beverage &p) : p(p) {}; В остальных случаях утечка есть, поскольку старое значение указателя beverage2 теряется. Например, я могу дописать код так, что утечки не будет: https://ideone.com/lhxozT #include 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

Ответ 2



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

Комментариев нет:

Отправить комментарий