Poprawność usunięcia obiektu tworzoznego przez new

0

Witam.
Proszę o wyjaśnienie moich wątpliwości:
Mam klasę np:

//plik "mywidget.h"
class MyWidget : public QWidget
{  Q_OBJECT
  public: 
  static void RunMethod();

  protected:
  void closeEvent(QCloseEvent*);
  private:
     explicit MyWidget (QWidget * parent = 0);
     ~MyWidget ();
}


//plik "mywidget.cpp"
MyWidget *obj = 0;

void MyWidget::RunMethod()
{
   obj = new MyWidget(NULL);
}

 void MyWidget:closeEvent(QCloseEvent*)
{
    obj = 0;
}

MyWidget ma właściwość taką, że przy zamykaniu ma nastąpić jego autodestrukcja ( ma sam siebie delete)
Teraz czy po przypisaniu w closeEwent() obj = 0 wskaźnik obj zostanie poprawnie usunięte z pamięci?

0

Nie. Do usuwania służy przecież delete.

0
//plik "mywidget.cpp"
MyWidget *obj = 0;
 
MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
   this->setAttribute(Qt::WA_DeleteOnClose); // zgodnie z dokumentacją ten atrybut powoduje delete na oknie, które jest zamykane
}

void MyWidget::RunMethod()
{
   if(!obj) {
     obj = new MyWidget(NULL);
    }
   obj->schowNormal();
}
 
 void MyWidget:closeEvent(QCloseEvent*)
{
    obj = 0;
}

Nie jasno chyba napisałem w pierwszym poście.
Okno obj może zostać zamknięte przez "krzyżyk" na belce okna. Po ustawieniu

setAttribute(Qt::WA_DeleteOnClose)

, obj ma się usunąć z pamięci (zostanie wywołany destruktor ~MyWidget();.
Teraz pytanie: czy przypisując:
void MyWidget:closeEvent(QCloseEvent*)

{
    obj = 0; czy to zeruje wartość wsk obj, zeruje pamięć obiektu obj, a może powoduje utratę informacji o pamięci zajmowanej przez obj?
}

Z tego co ja myślę, to obj = wskaźnik na pamięć zajmowaną przez

new  MyWidget(0);

, obj posiada własny wskaźnik na siebie -> this.
No to delete this = usunięcie (zwolnienie obiektu

new  MyWidget(0);

, a przypisanie obj = 0(NULL) zeruje wskazanie na new MyWidget(0);

. Teraz, czy pamięć przydzielona wskaźnikowi obj zostanie zwolniona po zamknięciu aplikacji, czy po prosru mamy memory leak?
CZy moje rozumowanie jest słuszne?
0

obj = 0; czy to zeruje wartość wsk obj, zeruje pamięć obiektu obj, a może powoduje utratę informacji o pamięci zajmowanej przez obj?

tutaj przypisujesz nulla to wskaźnika zatem tracisz na zawsze kontakt z obiektem chyba ,że pokazywał na dany obiekt jeszcze jakiś dodatkowy wskaźnik. Sam fizyczny obiekt będzie sobie nadal istniał zajmując pamięć. Jeśli wywołasz operator delete no najpierw uruchomi się destruktor obiektu a później zostanie zwolniona pamięć zajmowana przez niego.

0

Wskaźnik this jest to wskaźnik który jest po kryjomy przesyłany do funkcji RunMethod zawiera on informacje na temat obiektu na rzecz którego została wywołana metoda. Tutaj:

obj = new MyWidget(NULL);

tworzysz nowy obiekt typu MyWidget i przypisujesz jego adres do wskaźnika.
Tutaj:

obj = 0;

się dzieje to co już wcześniej powiedziałem.
Zatem gdzieś w programie zapewnie tworzysz obiekt główny i na rzecz niego wywołujesz metodę RunMethod:

MyWidget w;
w.RunMethod()

Zatem w tym przypadku this w środku metody RunMethod będzie tak jakby adresem zmiennej "w"
W tej linijce:

obj->schowNormal();

przesyłasz adres obiektu pokazywanego przez wskaźnik obj.
zatem istnieją 2 obiekty w odrębnych obszarach pamięci. Czyli obj = 0; nie mogło wpłynąć na obiekt w której w metodzie znalazła się ta instrukcja.

0

No i trzeba pisać więcej kodu, czego chciałem uniknąć.
Rozwijając: w programie mam inną klasę np. PopUp. W jakiejś metodzie z PopUp chcę skożystać z obj:
void PopUp::schowWindow(){

   MyWidget::RunMetchod(); // mogę tak, bo to metoda statyczna w MyWidget. Nie tworzę żadnych innych instancji MyWidget oprócz zmiennej obj
}

Jeszcze raz sprawdziłem moje rozwiązanie w QtCreator, działa: MyWidget po naciśnięciu "krzyżyka" zamyka się i wywoływany jest ~MyWidget (), pomimo że closeEvent() wcześniej ustawia obj = 0;. No ale że to działa to jeszcz nie znaczy że wszystko jest w porządku.
Czekam na dalsze opinie expertów od C++. ;).
Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1