eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programming › [c++]Prosta klasa, czemu nie wywołuje destruktorów?
Ilość wypowiedzi w tym wątku: 11

  • 1. Data: 2009-07-28 16:00:41
    Temat: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: "P.K.D" <g...@g...com>

    Tutaj ta klasa: http://paste.dprogramming.com/dpibqklz

    Chodzi o to, że gdy wywołuję server::clearList() to obiekty nie są
    niszczone, chyba dlatego, że lista zawiera wskaźniki. Jak to zrobić i
    czy da się zrobić tak, że destruktory będą wywoływane automatycznie?

    Jak się komuś nie chce linka czytać:

    W kodzie jest:
    server* srv = new server(name, address, port);

    A w konstruktorze
    servers.push_back(this);

    gdzie servers to statyczna w klasie server:
    static std::list<server *> servers;

    no ale gdy wywołuję metodę clear() z std::list nie są wywoływane
    destruktory elementów listy gdzie jest intrukcja:
    delete this;

    przez co nie jest zwalniana pamięć po zakończeniu programu. Chciałbym
    jednak by była i nie wiem jak to zrobić. Z góry dziękuję :)




    --
    Life is great, but still... we're all trapped. Each of us is stuck being
    who we are. Sometimes we fight to change ourselves, but ultimately this
    has little effect. We can change what we do, but we cannot change who we
    are.


  • 2. Data: 2009-07-28 17:52:03
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: grg12 <g...@c...at>

    P.K.D pisze:
    > Tutaj ta klasa: http://paste.dprogramming.com/dpibqklz
    >
    > Chodzi o to, że gdy wywołuję server::clearList() to obiekty nie są
    > niszczone, chyba dlatego, że lista zawiera wskaźniki. Jak to zrobić i
    > czy da się zrobić tak, że destruktory będą wywoływane automatycznie?

    Dokładnie dlatego - masz listę wskaźników na obiekty a nie obiektów -
    wywoływany jest więc "destruktor" wskaźnika :)
    Możesz np. w metodzie clearList przelecieć po wszystkich elementach
    zmiennej "servers" i wywołać ich destruktory np. tak:

    for(std::list<server *>::iterator ii=servers.begin();ii!=servers.end();
    ii++)
    {
    delete (*ii);
    }

    servers.clear();

    Tyle że ciało tej funkcji prawdopodobnie trzeba będzie zdefiniować poza
    klasą - w tym miejscu gdzie jest teraz destruktor jeszcze nie jest
    zadeklarowany.

    I jeszcze jedno - "delete this" w destruktorze to kiepski pomysł (no
    chyba że się coś w specyfikacji języka zmieniło?). Normalnie wywołanie
    destruktora jest konsekwencja wywołania delete - destruktor to "ostatnia
    szansa na posprzątanie zanim system zwolni pamięć" (np. zwolnić pliki,
    usunąć podobiekty utworzone przez new). W twoim przypadku destruktor
    może być pusty - jeśli koniecznie chcesz coś tam mieć - wstaw "std::cout
    << "obiekt typu server o nazwie"<<name<<" właśnie popełnia
    seppuku"<<std::endl;
    Pozdrawiam
    GRG


  • 3. Data: 2009-07-28 17:54:11
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: Tomasz Bywalec <t...@p...dont.spam.me.o2.pl>

    P.K.D pisze:
    > Tutaj ta klasa: http://paste.dprogramming.com/dpibqklz
    >
    > Chodzi o to, że gdy wywołuję server::clearList() to obiekty nie są
    > niszczone, chyba dlatego, że lista zawiera wskaźniki. Jak to zrobić i
    > czy da się zrobić tak, że destruktory będą wywoływane automatycznie?
    >
    > Jak się komuś nie chce linka czytać:
    >
    > W kodzie jest:
    > server* srv = new server(name, address, port);
    >
    > A w konstruktorze
    > servers.push_back(this);
    >
    > gdzie servers to statyczna w klasie server:
    > static std::list<server *> servers;
    >
    > no ale gdy wywołuję metodę clear() z std::list nie są wywoływane
    > destruktory elementów listy gdzie jest intrukcja:
    > delete this;

    Usuwanie elementów z listy (lub dowolnej innej stl'owej kolekcji)
    zawsze powoduje usunięcie tych elementów - tyle że w Twoim
    przypadku elementami listy są wskaźniki. W takim razie niszczone
    są właśnie wskaźniki ale nie obiekty na które wskazują.

    Do głowy przychodzą mi dwa sposoby:

    1. Napisać osobną klasę reprezentującą listę serwerów -
    przechowywałaby ona listę std::list<server*> jako pole
    prywatne, natomiast dostęp do listy odbywałby się
    przy pomocy metod 'add()' (dodaje wskaźnik do listy),
    'remove()' (usuwa wskaźnik i jednocześnie niszczy wskazywany
    przez niego obiekt) oraz 'clear()' (czyli 'remove()' dla
    wszystkich elementów listy) plus jakieś metody umożliwiające
    przeglądanie listy. I zastąpić typ pola 'servers' tą klasą.

    2. Zamiast std::list użyć boost::ptr_list, która po usunięciu
    wskaźnika z listy niszczy również wskazywany obiekt:

    http://www.boost.org/doc/libs/1_39_0/libs/ptr_contai
    ner/doc/ptr_container.html

    Pozdrawiam,
    Tomek Bywalec


  • 4. Data: 2009-07-28 20:11:26
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: "P.K.D" <g...@g...com>

    W dniu 2009-07-28 19:52, grg12 pisze:
    > P.K.D pisze:
    >> Tutaj ta klasa: http://paste.dprogramming.com/dpibqklz
    >>
    >> Chodzi o to, że gdy wywołuję server::clearList() to obiekty nie są
    >> niszczone, chyba dlatego, że lista zawiera wskaźniki. Jak to zrobić i
    >> czy da się zrobić tak, że destruktory będą wywoływane automatycznie?
    >
    > Dokładnie dlatego - masz listę wskaźników na obiekty a nie obiektów -
    > wywoływany jest więc "destruktor" wskaźnika :)
    > Możesz np. w metodzie clearList przelecieć po wszystkich elementach
    > zmiennej "servers" i wywołać ich destruktory np. tak:
    >
    > for(std::list<server *>::iterator ii=servers.begin();ii!=servers.end();
    > ii++)
    > {
    > delete (*ii);
    > }
    >
    > servers.clear();
    >
    > Tyle że ciało tej funkcji prawdopodobnie trzeba będzie zdefiniować poza
    > klasą - w tym miejscu gdzie jest teraz destruktor jeszcze nie jest
    > zadeklarowany.
    >
    > I jeszcze jedno - "delete this" w destruktorze to kiepski pomysł (no
    > chyba że się coś w specyfikacji języka zmieniło?). Normalnie wywołanie
    > destruktora jest konsekwencja wywołania delete - destruktor to "ostatnia
    > szansa na posprzątanie zanim system zwolni pamięć" (np. zwolnić pliki,
    > usunąć podobiekty utworzone przez new). W twoim przypadku destruktor
    > może być pusty - jeśli koniecznie chcesz coś tam mieć - wstaw "std::cout
    > << "obiekt typu server o nazwie"<<name<<" właśnie popełnia
    > seppuku"<<std::endl;
    > Pozdrawiam
    > GRG

    Ok, przemyślałem i faktycznie delete this to idiotyzm. Dzięki, że o tym
    wspomniałeś:) W końcu nie miałem wyjścia i zrobiłem swoją funkcję
    clear(), ale myślałem, że może jest jakiś inny sposób przewidziany do
    pracy z takimi listami. No ale niezadowolony jestem, bo chciałbym żeby
    ta lista się sama czyściła. Będę musiał chyba napisać osobną klasę jak
    to Tomasz opisał. Dzięki za odpowiedzi:)

    --
    Life is great, but still... we're all trapped. Each of us is stuck being
    who we are. Sometimes we fight to change ourselves, but ultimately this
    has little effect. We can change what we do, but we cannot change who we
    are.


  • 5. Data: 2009-07-29 11:37:07
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: "Mateusz Loskot" <m...@l...net>

    "P.K.D" <g...@g...com> wrote in message
    news:h4n80i$97a$1@mx1.internetia.pl...
    > przez co nie jest zwalniana pamięć po zakończeniu programu. Chciałbym
    > jednak by była i nie wiem jak to zrobić. Z góry dziękuję :)

    Po za kończeniu programu (procesu), pamięć zostanie zwolniona,
    o to się nie martw.

    Pozdrawiam
    --
    Mateusz Loskot, http://mateusz.loskot.net
    pl.comp.lang.c FAQ: http://pl.cpp.wikia.com/wiki/FAQ
    C++ FAQ: http://parashift.com/c++-faq-lite


  • 6. Data: 2009-07-29 11:37:33
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: Mariusz Kruk <M...@e...eu.org>

    epsilon$ while read LINE; do echo \>"$LINE"; done < "Mateusz Loskot"
    >> przez co nie jest zwalniana pamięć po zakończeniu programu. Chciałbym
    >> jednak by była i nie wiem jak to zrobić. Z góry dziękuję :)
    >Po za kończeniu programu (procesu), pamięć zostanie zwolniona,
    >o to się nie martw.

    "zakończeniu".
    Poza tym milcząco zakładasz, że środowisko samo posprząta. A nie zawsze
    tak jest. Sprzątanie po sobie jest dobrą praktyką.

    --
    \.\.\.\.\.\.\.\.\.\.\.\.\.\ (If you're confused by all this, try typing
    .\....@e...eu.org.\.\. `I}' now.)(TeX)
    \.http://epsilon.eu.org/\.\
    .\.\.\.\.\.\.\.\.\.\.\.\.\.


  • 7. Data: 2009-07-29 11:53:33
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: Tomasz Kaczanowski <kaczus@dowyciecia_poczta.onet.pl>

    P.K.D pisze:
    > W dniu 2009-07-28 19:52, grg12 pisze:
    >> P.K.D pisze:
    >>> Tutaj ta klasa: http://paste.dprogramming.com/dpibqklz
    >>>
    >>> Chodzi o to, że gdy wywołuję server::clearList() to obiekty nie są
    >>> niszczone, chyba dlatego, że lista zawiera wskaźniki. Jak to zrobić i
    >>> czy da się zrobić tak, że destruktory będą wywoływane automatycznie?
    >>
    >> Dokładnie dlatego - masz listę wskaźników na obiekty a nie obiektów -
    >> wywoływany jest więc "destruktor" wskaźnika :)
    >> Możesz np. w metodzie clearList przelecieć po wszystkich elementach
    >> zmiennej "servers" i wywołać ich destruktory np. tak:
    >>
    >> for(std::list<server *>::iterator ii=servers.begin();ii!=servers.end();
    >> ii++)
    >> {
    >> delete (*ii);
    >> }
    >>
    >> servers.clear();
    >>
    >> Tyle że ciało tej funkcji prawdopodobnie trzeba będzie zdefiniować poza
    >> klasą - w tym miejscu gdzie jest teraz destruktor jeszcze nie jest
    >> zadeklarowany.
    >>
    >> I jeszcze jedno - "delete this" w destruktorze to kiepski pomysł (no
    >> chyba że się coś w specyfikacji języka zmieniło?). Normalnie wywołanie
    >> destruktora jest konsekwencja wywołania delete - destruktor to "ostatnia
    >> szansa na posprzątanie zanim system zwolni pamięć" (np. zwolnić pliki,
    >> usunąć podobiekty utworzone przez new). W twoim przypadku destruktor
    >> może być pusty - jeśli koniecznie chcesz coś tam mieć - wstaw "std::cout
    >> << "obiekt typu server o nazwie"<<name<<" właśnie popełnia
    >> seppuku"<<std::endl;
    >> Pozdrawiam
    >> GRG
    >
    > Ok, przemyślałem i faktycznie delete this to idiotyzm. Dzięki, że o tym
    > wspomniałeś:) W końcu nie miałem wyjścia i zrobiłem swoją funkcję
    > clear(), ale myślałem, że może jest jakiś inny sposób przewidziany do
    > pracy z takimi listami. No ale niezadowolony jestem, bo chciałbym żeby
    > ta lista się sama czyściła. Będę musiał chyba napisać osobną klasę jak
    > to Tomasz opisał. Dzięki za odpowiedzi:)
    >

    Nie - jest bardzo dobrze - to co jest allokowane przez obiekt, czyścić
    powinien obiekt, jeśli ty allokujesz, to powinieneś ty zwalniać. Jeśli
    byłoby inaczej, nigdy byś nie wiedział, co zwalniać, a co nie i wtedy
    byłby bałagan.

    --
    Kaczus
    http://kaczus.republika.pl


  • 8. Data: 2009-07-29 12:29:12
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: Tomasz Bywalec <t...@p...dont.spam.me.o2.pl>

    Tomasz Kaczanowski pisze:
    [...]
    >
    > Nie - jest bardzo dobrze - to co jest allokowane przez obiekt, czyścić
    > powinien obiekt, jeśli ty allokujesz, to powinieneś ty zwalniać. Jeśli
    > byłoby inaczej, nigdy byś nie wiedział, co zwalniać, a co nie i wtedy
    > byłby bałagan.
    >

    Wydaje mi się, że przeoczyłeś fakt, że w oryginalnym kodzie P.K.D.
    "delete this;" jest wywoływane w destruktorze. Pod pewnymi warunkami
    jest to dopuszczalne w innych metodach obiektu, ale użycie tego w
    destruktorze może tylko narobić problemów. Jeżeli obiekt został
    utworzony na stosie to instrukcja ta bodajże doprowadzi do UB, jeśli
    natomiast obiekt znajduje się na stercie to "delete ten_obiekt;" zostało
    już wywołane i na pewno nie ma potrzeby wywoływania go ponownie na tym
    samym obiekcie.

    Pozdrawiam,
    Tomek Bywalec


  • 9. Data: 2009-07-29 12:53:23
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: "Mateusz Loskot" <m...@l...net>

    "Mariusz Kruk" <M...@e...eu.org> wrote in message
    news:slrnh70d3t.6ka.Mariusz.Kruk@epsilon.rdc.pl...
    > epsilon$ while read LINE; do echo \>"$LINE"; done < "Mateusz Loskot"
    >>> przez co nie jest zwalniana pamięć po zakończeniu programu. Chciałbym
    >>> jednak by była i nie wiem jak to zrobić. Z góry dziękuję :)
    >>Po za kończeniu programu (procesu), pamięć zostanie zwolniona,
    >>o to się nie martw.
    >
    > "zakończeniu".
    > Poza tym milcząco zakładasz, że środowisko samo posprząta. A nie zawsze
    > tak jest. Sprzątanie po sobie jest dobrą praktyką.


    Oczywiście, że jest dobrą praktyką, ale 1) chodziło mi o wskazanie
    pewnej niejednoznaczności w oryginalnym pytaniu 2) o dziwo, bywają
    sytuacje gdy nie ma potrzeby aby zawacać sobie tym głowę.

    Pozdrawiam
    --
    Mateusz Loskot, http://mateusz.loskot.net
    pl.comp.lang.c FAQ: http://pl.cpp.wikia.com/wiki/FAQ
    C++ FAQ: http://parashift.com/c++-faq-lite


  • 10. Data: 2009-07-29 12:54:33
    Temat: Re: [c++]Prosta klasa, czemu nie wywołuje destruktorów?
    Od: "Mateusz Loskot" <m...@l...net>

    "Mateusz Loskot" <m...@l...net> wrote in message
    news:h4pgko$gfi$1@inews.gazeta.pl...
    > 2) o dziwo, bywają sytuacje gdy nie ma potrzeby aby zawacać sobie tym
    > głowę.


    Na przykład, interesuje mnie prosty test:

    #include <new>
    int main(void)
    {
    std::size_t c = 0;
    while (new(std::nothrow) char)
    ++c;
    return c;
    }

    $ ./test
    $ echo $?

    Pozdrawiam
    --
    Mateusz Loskot, http://mateusz.loskot.net
    pl.comp.lang.c FAQ: http://pl.cpp.wikia.com/wiki/FAQ
    C++ FAQ: http://parashift.com/c++-faq-lite

strony : [ 1 ] . 2


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: