• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Konstruktory i destruktory - zrozumienie...

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
478 wizyt
pytanie zadane 22 września 2015 w C i C++ przez rafalmagician Obywatel (1,320 p.)

Mój kod:

MAIN:

#include <iostream>

using namespace std;

#include "statki.h"

int main()
{
    Zaglowiec z1("Fryderyk Chopin","3Oceans",4,27.5);
        z1.show();

    Parowiec p1("SS Soldek",200,3,"B33",30.7);
        p1.show();

    Kontenerowiec k1("Emma Marks",170.790,170.500);
        k1.show();

    Lotniskowiec l1("Nimitz",100.000,332.8,"2 reaktory atomowe o mocy 280,000 KM");
        l1.show();

    return 0;
}

statki.h:

#include <iostream>

using namespace std;

class Zaglowiec
{
    private:
        string nazwa;
        string rodzajZagli;
        int liczbaMasztow;
        float wysokoscNajwMasztu;

    public:
        Zaglowiec(string,string,int,float);
        ~Zaglowiec();
        void load();
        void show();
};
class Parowiec
{
    private:
        string nazwa;
        int liczbaPasazerow;
        int liczbaKotlow;
        string rodzajKotlow;
        float cisnienieParyDolotowej;

    public:
        Parowiec(string,int,int,string,float);
        ~Parowiec();
        void load();
        void show();
};
class Kontenerowiec
{
    private:
        string nazwa;
        double pojemnoscRejestrowa;
        double pojemnoscLadunkowa;

    public:
        Kontenerowiec(string,double,double);
        ~Kontenerowiec();
        void load();
        void show();
};
class Lotniskowiec
{
    private:
        string nazwa;
        double wypornosc;
        float dlugoscPasaStartowego;
        string rodzajNapedu;

    public:
        Lotniskowiec(string,double,float,string);
        ~Lotniskowiec();
        void load();
        void show();
};

 

statki.cpp:

#include <iostream>

using namespace std;

#include "statki.h"

//Zaglowiec:
Zaglowiec::Zaglowiec(string n,string rZ,int lM,float wNM)
{
    cout << endl;
    nazwa = n;
    rodzajZagli = rZ;
    liczbaMasztow = lM;
    wysokoscNajwMasztu = wNM;
}
Zaglowiec::~Zaglowiec()
{
    cout << endl << "Destruktor#1: Zaglowiec..." << endl;
}
void Zaglowiec::load()
{
    cout << "Podaj Dane Zaglowca: " << endl;
    cout << "#Nazwa#: ";
    cin >> nazwa;
    cout << "#Rodzaj Zagli#: ";
    cin >> rodzajZagli;
    cout << "#Liczba Masztow#: ";
    cin >> liczbaMasztow;
    cout << "#Wysokosc Najwiekszego Masztu#: ";
    cin >> wysokoscNajwMasztu;
}
void Zaglowiec::show()
{
    cout << "Dane Zaglowca: " << endl;
    cout << "Nazwa: " << nazwa << endl;
    cout << "Rodzaj Zagli: " << rodzajZagli << endl;
    cout << "Liczba Masztow: " << liczbaMasztow << endl;
    cout << "Wysokosc Najwiekszego Masztu: " << wysokoscNajwMasztu << endl;
}
//Parowiec:
Parowiec::Parowiec(string n,int lP,int lK,string rK,float cPD)
{
    cout << endl;
    nazwa = n;
    liczbaPasazerow = lP;
    liczbaKotlow = lK;
    rodzajKotlow = rK;
    cisnienieParyDolotowej = cPD;
}
Parowiec::~Parowiec()
{
    cout << endl << "Destruktor#2: Parowiec..." << endl;
}
void Parowiec::load()
{
    cout << "Podaj Dane Parowca: " << endl;
    cout << "#Nazwa#: ";
    cin >> nazwa;
    cout << "#Liczba Pasazerow#: ";
    cin >> liczbaPasazerow;
    cout << "#Liczba Kotlow#: ";
    cin >> liczbaKotlow;
    cout << "#Rodzaj Kotlow#: ";
    cin >> rodzajKotlow;
    cout << "#Cisnienie Pary Dolotowej#: ";
    cin >> cisnienieParyDolotowej;
}
void Parowiec::show()
{
    cout << "Dane Parowca: " << endl;
    cout << "Nazwa: " << nazwa << endl;
    cout << "Liczba Pasazerow: " << liczbaPasazerow << endl;
    cout << "Liczba Kotlow: " << liczbaKotlow << endl;
    cout << "Rodzaj Kotlow: " << rodzajKotlow << endl;
    cout << "Cisnienie Pary Dolotowej: " << cisnienieParyDolotowej << endl;
}
//Kontenerowiec:
Kontenerowiec::Kontenerowiec(string n,double pR,double pL)
{
    cout << endl;
    nazwa = n;
    pojemnoscRejestrowa = pR;
    pojemnoscLadunkowa = pL;
}
Kontenerowiec::~Kontenerowiec()
{
    cout << endl << "Destruktor#3: Kontenerowiec..." << endl;
}
void Kontenerowiec::load()
{
    cout << "Podaj Dane Kontenerowca: " << endl;
    cout << "#Nazwa#: ";
    cin >> nazwa;
    cout << "#Pojemnosc Rejestrowa#: ";
    cin >> pojemnoscRejestrowa;
    cout << "#Pojemnosc Ladunkowa#: ";
    cin >> pojemnoscLadunkowa;
}
void Kontenerowiec::show()
{
    cout << "Dane Kontenerowca: " << endl;
    cout << "Nazwa: " << nazwa << endl;
    cout << "Pojemnosc Rejestrowa: " << pojemnoscRejestrowa << endl;
    cout << "Pojemnosc Ladunkowa: " << pojemnoscLadunkowa << endl;
}
//Lotniskowiec:
Lotniskowiec::Lotniskowiec(string n,double w,float dPS,string rN)
{
    cout << endl;
    nazwa = n;
    wypornosc = w;
    dlugoscPasaStartowego = dPS;
    rodzajNapedu = rN;
}
Lotniskowiec::~Lotniskowiec()
{
    cout << endl << "Destruktor#4: Lotniskowiec..." << endl;
}
void Lotniskowiec::load()
{
    cout << "Podaj Dane Lotniskowca: " << endl;
    cout << "#Nazwa#: ";
    cin >> nazwa;
    cout << "#Wypornosc#: ";
    cin >> wypornosc;
    cout << "#Dludosc Pasa Startowego#: ";
    cin >> dlugoscPasaStartowego;
    cout << "#Rodzaj Napedu#: ";
    cin >> rodzajNapedu;
}
void Lotniskowiec::show()
{
    cout << "Dane Lotniskowca: " << endl;
    cout << "Nazwa: " << nazwa << endl;
    cout << "Wypornosc: " << wypornosc << endl;
    cout << "Dlugosc Pasa Startowego: " << dlugoscPasaStartowego << endl;
    cout << "Rodzaj Napedu: " << rodzajNapedu << endl;
}

I w konsoli:

I mam pytanie co do destruktorów:

Dlaczego destruktory wykonują się na końcu a nie zaraz po wyświetleniu konstruktora ?? Moim zdaniem po każdym wyświetleniu informacji o danym statku powinien zaraz po wykonać się destruktor...

Dzięki za pomoc :)

6 odpowiedzi

+3 głosów
odpowiedź 22 września 2015 przez niezalogowany
Konstruktor jest wywoływany po utworzeniu (konstrukcji) obiektu. PO UTWORZENIU - on nie tworzy obiektu, on jest takim dekoratorem wnętrz (porównania z ,,Symfonii C++" Jerzego Grębosza ;)), dekorator wchodzi do gotowego domu i robi to co ma tam zrobić, czyli "ustawia meble", dodaje jakieś szczegóły (na przykład inicjuje zmienne jakimiś wartościami).

Destruktor jest wywoływany przed zniszczeniem (destrukcją) obiektu. PRZED DESTRUKCJĄ - nie niszczy obiektu, on jest taką sprzątaczką (kolejne porównanie z książki ;)), która sprząta trochę w domu, zabiera niektóre rzeczy, które nie można było wziąć po zniszczeniu (na przykład usuwa pamięć zajętą przez dynamiczny obiekt, czyli zwykła instrukcja delete, tylko że ty masz języl C, a nie C++, więc nie wiem czy tam taka instrukcja jest ;)), a następnie się niszczy obiekt.

Jak chcesz wywołać destruktor jawnie, czyli chcesz, żebyś ty wywołał destruktor, a nie automatycznie, to robisz to tak:
obiekt.~NazwaKlasy();
Proste, co nie? :)
komentarz 22 września 2015 przez Patrycjerz Mędrzec (192,320 p.)

Ciekawa analogia do dekorowania domu meblami wink Masz za to łapencję yes

komentarz 22 września 2015 przez niezalogowany
A tam, taką mentalną łapkę w górę daj Jurkowi Gręboszowi ;) A tak poza tematem, to zakładam zaraz taką dyskusję o SFML-u, sprawdź za jakieś 5 min. ;) Mam nadzieję, że sheadovas też sprawdzi ;)
komentarz 22 września 2015 przez Patrycjerz Mędrzec (192,320 p.)
Wiesz co? Jeśli problem nie jest zbyt rozbudowany, to może sam ci pomogę. Napisz na PW.
komentarz 22 września 2015 przez niezalogowany
Też tak myślałem na początku, ale chciałem też zobaczyć odpowiedź sheadovasa, więc nie będę pisał na PW dwa razy. A do tego może poznam odpowiedzi innych forumowiczów ;) Temat założony!
0 głosów
odpowiedź 22 września 2015 przez event15 Szeryf (93,790 p.)

Destruktor jest specjalną funkcją, która jest wywoływana zawsze tuż przed zniszczeniem (usunięciem) klasy z pamięci.

 

0 głosów
odpowiedź 22 września 2015 przez Ehlert Ekspert (214,270 p.)
Ale w żadnym miejscu po wyświetleniu informacji nie wywoałeś destruktora jawnie.
0 głosów
odpowiedź 22 września 2015 przez Krawiec91 Pasjonat (19,600 p.)
Konstruktor wywoływany jest, gdy tworzony jest obiekt danej klasy (zresztą, sama nazwa wskazuje, konstruktor czy ktoś/coś co tworzy, konstruuje). Destruktor natomiast jest wywoływany przy usuwania obiektu danej klasy (nazwa też sugeruje, destrukcja, czyli niszczenie. W przypadku Twojego programu destruktory są wywoływane w momencie zakończenia programu. Dobrze widać działanie destruktorów i konstruktorów przy dynamicznym alokowaniu obiektów (operatory new i delete). W momencie utworzenia obiektu (operator new) wywoływany jest konstruktor, a przy zwalnianiu zaalokowanej na obiekt pamięci (operator delete) wywoływany jest destruktor.
0 głosów
odpowiedź 22 września 2015 przez baszmest Gaduła (3,080 p.)

Destruktor wywołuje się gdy usuwany jest obiekt. -> Obiekt usuwany jest gdy program "dojdzie do konca obszaru" w którym ten obiekt się znajduje. Ten obszar, czyli zasięg wyznaczaja klamry { }. -> U ciebie obiekty są w zasięgu main'a().  Więc dopiero gdy program dojdzie do klamry zamykajacej main'a () obiekt jest usuwany i wywołuje się destruktor. Jeśli każdy z obiektów zamknął byś w  osobnych klamrach, to efekt byłby taki jaki chciałes, czyli: 
dane zaglowca
destruktor 1
dane parowca
destruktor 2
 

int main()
{
     {
        Zaglowiec z1("Fryderyk Chopin","3Oceans",4,27.5);
        z1.show();
     }
     {
         Parowiec p1("SS Soldek",200,3,"B33",30.7);
        p1.show();
     } 
    return 0;
}

 

Tak przynajmniej mi się wydaje, według tego: http://cpp0x.pl/kursy/Programowanie-obiektowe-C++/Podstawy/Konstruktory-i-destruktory/490 - Patrz przykład na dole strony

komentarz 22 września 2015 przez niezalogowany
Dobrze dobrze ci się wydaje ;) O zakresie nie napisałem, więc masz łapkę w górę :3
komentarz 22 września 2015 przez baszmest Gaduła (3,080 p.)
Autor pytania dostał już tyle odpowiedzi, że powinien to zrozumieć :)
komentarz 22 września 2015 przez niezalogowany
Ale łapki nie cofnę! ;D No, tylko że w tym dwie nie tłumaczyły za wiele ;) Ale tak, pewnie już zrozumiał ;)
–1 głos
odpowiedź 22 września 2015 przez criss Mędrzec (172,590 p.)
Ekhm, ale dlaczego tak sądzisz? o_O Nazwa ci niczego nie sugeruje?
komentarz 22 września 2015 przez rafalmagician Obywatel (1,320 p.)
Tak myśle że powinno być:

dane zaglowca

destruktor 1

dane parowca

destruktor 2

itd....

Skoro destruktor jest wywoływany w tym samym obiekcie to powinien wykonać się odrazu ... ??
komentarz 22 września 2015 przez Ehlert Ekspert (214,270 p.)

Dopisz:

Zaglowiec z1("Fryderyk Chopin","3Oceans",4,27.5);
        z1.show();
        z1.~Zaglowiec();

 

komentarz 22 września 2015 przez criss Mędrzec (172,590 p.)
No dobrze, ale destruktor jest wykonywany tuz przed usunieciem obiektu z pamieci, a ty ich nie usuwasz (nawet nie masz jak bo nie sa dynamicznie zaalokowane). Program sam je usuwa na koniec wykonywania programu dlatego są wyswietlane na koncu. Nie bardzo wiem o co ci chodzi jesli wiesz co to jest destuktor.

Podobne pytania

0 głosów
2 odpowiedzi 657 wizyt
0 głosów
1 odpowiedź 495 wizyt
0 głosów
1 odpowiedź 520 wizyt
pytanie zadane 3 grudnia 2016 w C i C++ przez Sinnley Stary wyjadacz (12,810 p.)

93,107 zapytań

142,082 odpowiedzi

321,605 komentarzy

62,447 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...