Zniszczenie obiektu skazywanego przez wskaźnik a destruktor

0

Witam !

Mam pytanie chodzi mi mianowicie o niszczenie obiektu na który wskazuje wskaźnik, ale nie chodzi mi tutaj o coś w stylu :

 
nazwa_klasy *nowy = new nazwa_klasy();
delete nowy;

Zależy mi, aby to wszystko działo się w destruktorze mianowicie coś takiego:

 
#include <iostream>
#include<cstdlib>

using namespace std;

class pp
{
private :
    int wartosc;
public:
    pp():wartosc(rand()%100){}
    ~pp();
    void show();
};

pp::~pp()
{
    // usuniecie obiektu wskazywanego
}

void pp::show()
{
    cout << wartosc << endl;
}

int main()
{
    pp *nowy = new pp();
    nowy->show();

    nowy->~pp();

    return 0;
}

Próbowałem coś w stylu:

 
pp::~pp()
{
   delete this;
}

Ale nic z tego, z góry dzięki za pomoc.

Pozdrawiam.

0

Nie, to nie tak. Jeśli stworzyłeś

pp* nowy = new pp();

to masz usuwać przez

delete nowy;

Są wyjątki: http://stackoverflow.com/questions/14187006/is-calling-destructor-manually-always-a-sign-of-a-bad-design

Załóżmy przez chwilę, że Twój zapis jest poprawny, to w czym nowy->~pp() jest lepsze od delete nowy? I tu i tu masz jedną linijkę kodu, która usuwa.

Zadaniem destruktora jest usuwanie zmiennych klasy alokowanych dynamicznie, a nie usuwanie obiektu klasy (usuwanie siebie). Ogólnie klasa może popełnić samobójstwo delete this, ale to jest zupełnie inny przypadek niż Twój i na razie nie zawracaj sobie tym głowy.

0

No to zadam pytanie inaczej a co jeśli mam listę :

 
#include <iostream>
#include <cstdlib>

using namespace std;

class kulka
{
private:
    int wartosc;
    int id; // numer porzadkowy tworzenia obiektu
    kulka *next;
public:
    //konstruktor
    kulka(int my_id):id(my_id),wartosc(rand()%100),next(NULL)
    {
        cout << "Towrze obiekt! Nr." << id << " o wartosci : " << wartosc << endl;
    }
    //dekonstruktor
    ~kulka();
    //metody
    void add(kulka *wskaznik);
    void show();
};

kulka::~kulka()
{

}

void kulka::add(kulka *wskaznik)
{
    if(next==NULL)next=wskaznik; //istnieje tylko element pierwszy z maina
    else
    {
        kulka *tmp = next;
        while(tmp->next)
        {
            tmp=tmp->next;
        }
        tmp->next=wskaznik;
    }
}

void kulka::show()
{
    cout << "Id :" << id << " wartosc to :" << wartosc << endl;
    if(next!=NULL)next->show();
}

int main()
{
    kulka *first = new kulka(0);

    for(int i=1;i<10;i++)
    {
        kulka *nowa = new kulka(i);
        first->add(nowa);
    }
    cout << "Lista: " << endl;
    first->show();

    first->~kulka();

    return 0;
}

Od razu mówię ,że potrafił bym usunąć z niej (przez destruktor) wszystkie elementy tej listy prócz właśnie pierwszego firsta bo nie mam jak się do niego odwołać w destruktorze (mam jedynie dostęp do jego składowych). I tu moje pytanie jak.

0

Zrób klasę KolekcjaKulek w której będziesz miał składową: kulka *first; i która będzie mieć ten destruktor.

0

TAK wiem ,że tak powinno się robić listy na 2 klasach z czego jedna trzyma firsta ale mój "mądry" prowadzący laboratoria uparł się że mamy pisać na 1 klasie. I tu moje pytanie jak to można ugryźć z tej strony ?

1
#include <iostream>
using namespace std;

struct StupidClass
{
	StupidClass* next;
	
	StupidClass() { cout << "Creating" << endl; }
	~StupidClass() { cout << "Deleting" << endl; delete next; }
	void add(StupidClass*);
};

void StupidClass::add(StupidClass* wskaznik)
{
    if(next==NULL)next=wskaznik; //istnieje tylko element pierwszy z maina
    else
    {
        StupidClass *tmp = next;
        while(tmp->next)
        {
            tmp=tmp->next;
        }
        tmp->next=wskaznik;
    }
}

int main() 
{
	StupidClass* first = new StupidClass;
	for (int i = 0; i < 5; ++i)
	{
		first->add(new StupidClass());
	}
	
	delete first;
	return 0;
}
0

Czyli mam rozumieć że nie ma metody na zniszczenie firsta bezpośrednio z destruktora w takim wypadku?

2

Z destruktora czego? Może tak ci bardziej pasuje:

int main() 
  {
   StupidClass First,*first=&First;
   for(int i=0;i<5;++i) first->add(new StupidClass());
   return 0;
  }
0
_13th_Dragon napisał(a):

Z destruktora czego? Może tak ci bardziej pasuje:

int main() 
  {
   StupidClass First,*first=&First;
   for(int i=0;i<5;++i) first->add(new StupidClass());
   return 0;
  }

To faktycznie fajne rozwiązanie :) dzięki, ale teraz napisałem tak:

kulka::~kulka()
{
    cout << "Usuwam : " << wartosc << endl; // wartosc pierwszego elemntu
    kulka * aka_first = next;
    kulka * tmp = next;
    while(aka_first)
    {
        aka_first = tmp->next;
        cout << "Usuwam : " << tmp->wartosc << endl;
        delete tmp;
        tmp = aka_first;
    }
}
 

Wydaje mi się że powinno być ok a kompilator wyświetla mi jakieś głupoty :/

Ten kod kolegi wyżej działa bez zarzutu, ale chciał bym wiedzieć co z moim destruktorem jest nie tak ...

twonek napisał(a):
#include <iostream>
using namespace std;

struct StupidClass
{
	StupidClass* next;
	
	StupidClass() { cout << "Creating" << endl; }
	~StupidClass() { cout << "Deleting" << endl; delete next; }
	void add(StupidClass*);
};

void StupidClass::add(StupidClass* wskaznik)
{
    if(next==NULL)next=wskaznik; //istnieje tylko element pierwszy z maina
    else
    {
        StupidClass *tmp = next;
        while(tmp->next)
        {
            tmp=tmp->next;
        }
        tmp->next=wskaznik;
    }
}

int main() 
{
	StupidClass* first = new StupidClass;
	for (int i = 0; i < 5; ++i)
	{
		first->add(new StupidClass());
	}
	
	delete first;
	return 0;
}
1

Załóżmy że masz kilka obiektów typu kulka w takim łańcuszku.
Nazwijmy je A,B,C,D, ...
Destruktor A usuwa więc odpala destruktory B,C,D
Destruktor B usuwa więc odpala destruktory C,D
Destruktor C usuwa więc odpala destruktory D
Czy widzisz że usuwanie obiektu D odbywa się wielokrotnie?

0

Chyba rozumie:)

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