Smart pointers and virtual destructors
Ostatnio zmodyfikowano 2022-08-15 22:23
krystian123456 Temat założony przez niniejszego użytkownika |
Smart pointers and virtual destructors » 2022-08-12 17:00:58 Czy jest sens pisać w ogóle destruktory w klasach a tym bardziej jako wirtualnie jeśli używamy inteligentnych wskaźników, przez co pamięć jest i tak czyszczona automatycznie ? |
|
DejaVu |
» 2022-08-13 12:55:14 Inteligentne wskaźniki 'nie gwarantują' usunięcia całej pamięci. One gwarantują tylko, że destruktor zostanie automatycznie wywołany, gdy ostatnie odwołanie do instancji obiektu przestanie istnieć. class X { public: X() : m_x( new int ) { } private: int * m_x; };
Ta klasa będzie generowała Ci memory leak niezależnie od tego czy użyjesz ją na stosie czy stercie. Nie ważne czy opakujesz ją w std::shared_ptr<> czy nie. Dokładnie taki sam efekt (memory leak) uzyskasz pisząc: { std::shared_ptr < X > refX = std::make_shared < X >(); }
/edit: Nawiązując do 'wirtualnych destruktorów' - one również są potrzebne po to, aby właściwy destruktor się wywołał. Jak tego nie będziesz robił, to również prosisz się o memory leaki. Przykład: class Bazowa { public: Bazowa() { } };
class Pochodna : Bazowa { public: Pochodna() : m_x( new int ) { } ~Pochodna() { delete m_x; } private: int * m_x; }
int main() { std::shared_ptr < Bazowa > refX = std::make_shared < Pochodna >(); } int main() { std::shared_ptr < Pochodna > refX = std::make_shared < Pochodna >(); } Natomiast, aby w pierwszym scenariuszu nie było memory leak-a, to wystarczy do klasy bazowej dopisać wirtualny destruktor: class Bazowa { public: Bazowa() { } virtual ~Bazowa() { } };
|
|
krystian123456 Temat założony przez niniejszego użytkownika |
» 2022-08-14 00:25:09 A co gdyby zamiast int* m_x , zastąpić go też inteligentnym wskaźnikiem , czy zmieniło by to wiele ? class Bazowa { public: Bazowa() { } };
class Pochodna : public Bazowa { public: Pochodna() : m_x( std::make_shared < int >() ) { } ~Pochodna() { } private: std::shared_ptr < int > m_x; };
int main() { std::shared_ptr < Bazowa > refX = std::make_shared < Pochodna >(); return 0; }
|
|
DejaVu |
» 2022-08-14 00:49:50 Skoro destruktor ~Pochodna się nie wywoła to spodziewaj się memory leaków. Jak nie jesteś pewien co się stanie to możesz zamiast typu 'int' podstawić klasę, która w destruktorze wypisuje wartość. Niemniej jednak sprawdzisz zachowanie danego kompilatora, a nie standardu.
Skup się na pisaniu poprawnego kodu, a nie zastanawiaj się 'czy kod się zachowa dobrze, jak źle go będę pisał'. Nawet jak dziś zadziała dobrze, to za rok projekt może Ci się zacząć składać w różnych miejscach i potem będziesz tracił niepotrzebnie czas. |
|
krystian123456 Temat założony przez niniejszego użytkownika |
» 2022-08-14 11:19:23 Czyli rozumiem że mimo wszystko i tak powinien być tam destruktor wirtualny ? A jeszcze czy istnieją przykłady gdzie nie używać inteligentnych wskaźników, tylko trzeba zwykłych? |
|
pekfos |
» 2022-08-14 13:29:08 A jeszcze czy istnieją przykłady gdzie nie używać inteligentnych wskaźników, tylko trzeba zwykłych? Zawsze gdy nie Ty odpowiadasz za zwolnienie pamięci. |
|
krystian123456 Temat założony przez niniejszego użytkownika |
» 2022-08-15 22:23:10 Dziękuje za pomoc |
|
« 1 » |