#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 #includeusing 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, сборки мусора, к счастью, нет :) И еще - очень надеюсь, что вы знаете, что если удаляете наследника через указатель на предка - то деструктор должен быть виртуальным?...
Комментариев нет:
Отправить комментарий