Jak poprawnie zadeklarować destruktor ?

2015-02-23 15:42
0

Chciałem napisać przykładowy program tylko po to aby zobaczyć jak działa destruktor. Nie wiem czemu w 16 linii pokazuje mi taki błąd: expected class-name before '(' token.

Nie widzę tu błędu, robiłem tak jak jest w symfonii c++
Kod:

 #include <iostream>

using namespace std;
class numer
{
    public:
    string imie;
    int liczba;
    numer(string nazwa, int cyfra)
    {
        imie = nazwa;
        liczba = cyfra;
    }
    ~gadula();

};
int main()
{
    numer st("Tomek",20);
    st.~gadula();

    return 0;

}
gadula::~gadula()
    {
        cout << imie << " jest kasowane\n";
    }

Pozostało 580 znaków

2015-02-23 15:45
6

Bo zaiste moc copy-paste jest w tobie silna młody padawanie. Destruktor ma taką samą nazwę jak klasa tylko ze znaczkiem ~. Tak samo jak konstruktor musi sie nazywać tak samo jak klasa.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2015-02-23 16:16
2

nie musisz w ogóle sobie nim zawracać głowy, jak będziesz się stosował do RAII

http://pl.wikipedia.org/wiki/[...]Acquisition_Is_Initialization

edytowany 1x, ostatnio: gośćabc, 2015-02-23 16:18

Pozostało 580 znaków

2015-02-23 16:18
2

Oprócz tego co @Shalom napisał

st.~gadula();

nie tak się używa destruktora. Prawie nigdy nie masz potrzeby wywołania destruktora ręcznie. Sam się wywoła, gdy obiekt ma być zniszczony.

Pozostało 580 znaków

2015-02-23 17:00
0

Czemu jak skompiluje i uruchomie ten kod, to pojawiają się dziwne znacznki a nie napis, że "Tomek jest kasowane" ?

#include <iostream>

using namespace std;
class numer
{
    public:
    string imie;
    int liczba;
    numer(string nazwa, int cyfra)
    {
        imie = nazwa;
        liczba = cyfra;
    }
    ~numer(void);

};
int main()
{
    numer st("Tomek",20);
    st.~numer();

    return 0;

}
numer::~numer()
    {
        cout << imie << " jest kasowane\n";
    }

Pozostało 580 znaków

2015-02-23 17:05
0

~numer(void);wywal void.

A potem wywal wywołanie wywołanie destruktora z main.

nie pomogło. - nowicjusz35 2015-02-23 17:27

Pozostało 580 znaków

2015-02-23 17:07
2

pojawia się, tylko pewnie nie widzisz bo masz double delete (segfault)

edit:
mogłem być tutaj lekko nieprecyzyjny, zaraz ktoś to wytłumaczy

prawda jest taka, że double delete jest tylko na std::string a nie na całym obiekcie

dowody napisane przez @kq:
http://melpon.org/wandbox/permlink/bgnVAHFOY447VWfq

http://melpon.org/wandbox/permlink/PXGQeFi0OzjP9PlW

edit:

2015-02-23 17:44:21 < K-ballo> The lifetime of an object of type T ends when:
2015-02-23 17:44:21 < K-ballo> (1.3) — if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
2015-02-23 17:44:21 < K-ballo> (1.4) — the storage which the object occupies is reused or released.
2015-02-23 17:44:56 < K-ballo> so if is_trivially_destructible<foo> holds then x.~foo(); doesn't actually end its lifetime
...
2015-02-23 17:46:22 < K-ballo> yap, because string is not trivially destructible, so foo implicit's destructor is not trivial either

czyli @Endrju miał rację i jest UB

dodanie znacznika <quote> - @furious programming

edytowany 4x, ostatnio: furious programming, 2015-02-24 00:10
Pokaż pozostałe 4 komentarze
Ale tu nie ma niczego do badania. Podwójne wywołanie destruktora to UB. (12.4.15, nawet w example jest dokładnie opisana ta sytuacja) - Endrju 2015-02-23 17:50
Właśnie aktywowałeś moją kartę pułapkę! - spartanPAGE 2015-02-23 17:51
@Endrju chodzi o to, że gdyby nie było u niego w structcie stringa, a wywołałby destruktor, to dalej mógłby używać inta bez przeszkód http://melpon.org/wandbox/permlink/Mwosr6ygsHPyI3qZ bo int jest trivial type, i to niby nie jest już ub; - gośćabc 2015-02-23 17:56
Bzdura. Aboslutnie nie. Po wywołaniu destruktora obiekt st nie istnieje i nie można niczego z niego używać. (12.7.1) W tym co podałeś nie ma UB, bo destruktor nie kończy życia obiektu dlatego, że jest trywialny (3.8.1). - Endrju 2015-02-23 18:00
no właśnie dlatego skasowałem koment bo tak mi się wydawało - gośćabc 2015-02-23 18:11

Pozostało 580 znaków

2015-02-23 21:56
0

Ok, bo w symfonii miałem podany przykład wywołania ręcznego destruktora, coś w podobie do tego programu. Tam nie było stringa tylko tablica znaków.

Pokaż. Zrób fotkę, przepisz albo coś. - Endrju 2015-02-23 22:00
wieczorem napisze. - nowicjusz35 2015-02-24 17:15

Pozostało 580 znaków

2015-02-25 00:24
0

Program z symfonii na ręczne wywołanie destruktora:

#include <cstring>
#include <iostream>
using namespace std;

class gadula
{
    int licz;
    char tekst[40];
public:
    gadula(int k, const char *opis);
    ~gadula(void);

    int zwracaj() {return licz;}
    void schowaj(int x) {licz = x;}
    void coto()
    {
        cout << tekst  << " ma wartosc " << licz << endl;
    }
};
gadula::gadula(int k, const char *opis)
{
    strcpy(tekst,(opis ? opis : ""));
    licz = k;
    cout << "Konstruuje obiekt " << tekst << endl;
}
gadula::~gadula()
{
    cout << "Pracuje detruktor (sprzata) " << tekst << endl;
}
gadula a(1, "obiekt a (GLOBALNY)");
gadula b(2, "obiekt b (GLOBALNY)");

int main()
{
    a.coto();
    b.coto();
    {
        cout << "Poczatek lokalnego zakresu---\n";
        gadula c(30, "obiekt c (lokalny");
        gadula a(40, "obiekt a (lokalny)");

        cout << "\nCo teraz mamy :\n";
        a.coto();
        b.coto();
        c.coto();

        cout << "Do zaslonietego obiektu globalnego mozna sie jednak dostac\n";
        ::a.coto();
        cout << "Konczy sie lokalny zakres ----\n";
    }
    cout << "Juz jestem poza blokiem \n";
    a.coto();
    b.coto();
    cout << "Sam uruchamian destruktor obiektu a\n";
    a.~gadula();
    cout << "Koniec programu !!!!!\n";
}
co to za wersja symfoni? - fasadin 2015-02-25 09:25
Undefined behavior. - Endrju 2015-02-25 11:32
symfonia c++ standard - nowicjusz35 2015-02-26 17:11

Pozostało 580 znaków

2015-02-26 18:44
0

A na czym te UB polega ? Bo jak ten program wkleiłem do code::blocksa to dobrze działa (ten z symfonii program).

Pozostało 580 znaków

2015-02-26 19:26
2

Obiekt a jest globalny. Jego destruktor zostanie uruchomiony po zakończeniu funkcji main. Jednak w funkcji main jest on wywoływany ręcznie. Nietrywialny destruktor kończy życie obiektu, ponowne wywołanie destruktora dla tego obiektu powoduje undefined behavior po zakończeniu main.

Jak widać ta książka jest nietylko przestarzała ale zawiera też poważne błędy.


"(...) otherwise, the behavior is undefined".
edytowany 1x, ostatnio: Endrju, 2015-02-26 19:27
Pokaż pozostałe 2 komentarze
nie ma szans napisać takiego klocka bezbłędnie, a zwłaszcza po polsku - gośćabc 2015-02-27 09:48
@MSM Kanał #4programmers w sieci polnet. :-) - n0name_l 2015-02-27 10:09
@MSM nie ma sensu wbijać na ten kanał po tam z reguły nic się nie dzieje. Czasami tylko @Endrju pisze o UB, a @n0name_l przekonuje wszystkich do przesiadki na Powershella ;P - satirev 2015-02-27 20:02
Klamstwa! :-D - Endrju 2015-02-27 20:04
Sama prawda ;) - satirev 2015-02-27 20:07

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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