Jak poprawnie zadeklarować destruktor ?

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";
    }
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.

2

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

http://pl.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization

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.

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";
    }
 
0

~numer(void);wywal void.

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

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 1721 < K-ballo> The lifetime of an object of type T ends when:
2015-02-23 1721 < 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 1721 < K-ballo> (1.4) — the storage which the object occupies is reused or released.
2015-02-23 1756 < K-ballo> so if is_trivially_destructible<foo> holds then x.~foo(); doesn't actually end its lifetime
...
2015-02-23 1722 < 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

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.

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";
}
 
0

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

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.

0

Bo właśnie w symfonii na podstawie tego programu jest wytłumaczone co to jest destruktor. W opisie jest, że mimo wywowaliśmy go ręcznie to i tak on zostanie potem sam wywołany.

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