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

Tablkica wskaźników na obiekty klas bazowych - polimorfizm.

Object Storage Arubacloud
0 głosów
252 wizyt
pytanie zadane 21 maja 2020 w C i C++ przez Sobczyk Nowicjusz (150 p.)

Witam,

Mam do napisania program którego zadaniem jest tworzenie wydarzeń i wyswietlanie ich pełnej listy. Program ma działać na podstawie tablicy wskaznikow na obiekty klasy bazowej. Problem w tym, że utworzone obiekty giną po zakończeniu bloku kodu co skutkuje tym że tablica nie wyświetla wydarzen prawidłowo.

Klasa Wydarzenie jest klasa bazową z metoda wirtualna "wypisz", dziedziczą po niej pola daty oraz opis klasy pochodne Koncert oraz WystawaMalarska. Nie zabardzo wiem jak obejść "zanikanie" stworzonych obiektów. Do przechowywania wskaznikow wykorzystalem vector.

Niżej main kodu, same definicje klas jak i wykorzystane funkcje są proste więc nie uwzględniam ich w poście.

int main()
{
    int ster = 0;
    vector <Wydarzenie*> tablica_wydarzen;
    bool koniec = 0;
    do{
        ster = 0;
        cout<<"Wybierz opcje: "<<endl;
        cout<<"1 - Dodaj wydarzenie"<<endl;
        cout<<"2 - Wyswietl tablice wydarzen"<<endl;
        cout<<"3 - Zakoncz dzialanie"<<endl;
        cin>>ster;
        switch (ster)
        {
            case 1:
                {
                    system("cls");
                    char ster2;
                    cout<<"Jakie wydarzenie chcesz dodac?"<<endl<<endl;
                    cout<<"w - Nowe wydarzenie"<<"\nk - Nowy koncert"<<"\nm - Nowa wystawa malarska"<<"\np - Powrot"<<endl;
                    cin>>ster2;
                    switch (ster2)
                    {
                    case 'w':
                        {
                            Wydarzenie W;
                            nowe_wydarzenie(&W);
                            tablica_wydarzen.push_back(&W);
                            break;
                        }
                    case 'k':
                        {
                            Koncert K;
                            nowy_koncert(&K);
                            tablica_wydarzen.push_back(&K);
                            break;
                        }
                    case 'm':
                        {
                            WystawaMalarska WM;
                            nowa_wystawa(&WM);
                            tablica_wydarzen.push_back(&WM);
                            break;
                        }
                    default:
                        break;
                    }
                    koniec = 0;
                    break;
                }
            case 2:
                system("cls");
                for(int i=0; i<tablica_wydarzen.size();i++)
                    tablica_wydarzen[i]->wypisz();
                koniec = 0;
                break;
            case 3:
                system("cls");
                koniec = 1;
                break;
        }

    }while (koniec == 0);

    return 0;
}

 

1 odpowiedź

0 głosów
odpowiedź 21 maja 2020 przez adrian17 Ekspert (344,860 p.)
wybrane 21 maja 2020 przez Sobczyk
 
Najlepsza
                            Wydarzenie W;
                            nowe_wydarzenie(&W);
                            tablica_wydarzen.push_back(&W);

Tworzysz tutaj zmienną lokalną i przekazujesz jej adres do wektora, po czym zmienna lokalna ginie. Rozwiązaniem jest zaalokować obiekt dynamicznie (`new` lub smart pointer, jeśli możesz).

A swoją drogą...

nowe_wydarzenie(&W);

Skoro już pracujesz na klasach, to ta funkcja wygląda jak coś co powinno być w konstruktorze, nie?

komentarz 21 maja 2020 przez Sobczyk Nowicjusz (150 p.)
Wlasnie dopiero dzis doczytałem sie o istnieniu smart pointerow i nie zabardzo umiem je zaimplementowac a co do tej funkcji to zanim doszedłem do tego Obiekt jest lokalny to szukałem błędów nawet w konstruktorach i probowalem roznymi sposobami tworzyc obiekty, akurat ta wersje kodu mialem pod reka piszac post.
komentarz 21 maja 2020 przez adrian17 Ekspert (344,860 p.)
No to po klasycznemu, użyj zwykłe new/delete do dynamicznej alokacji obiektu.
komentarz 21 maja 2020 przez Sobczyk Nowicjusz (150 p.)
To rozumiem ze przy tworzeniu obiektu jakiejkolwiek klasy musze dodac owy new oraz delete do kazdego z nich na koncu programu, a co jeśli np odpale program ale stworze tylko jeden obiekt a do stworzenia reszty nie dojdzie?
komentarz 21 maja 2020 przez adrian17 Ekspert (344,860 p.)

To rozumiem ze przy tworzeniu obiektu jakiejkolwiek klasy musze dodac owy new oraz delete

Do do każdego obiektu jakiejkolwiek klasy. Przecież nie pisałeś `new vector` ;)  Ale musisz, gdy chcesz trzymać wskaźniki na obiekty i żeby te obiekty żyły dłużej niż ich scope.

a co jeśli np odpale program ale stworze tylko jeden obiekt a do stworzenia reszty nie dojdzie?

Nie zrozumiałem pytania :/

komentarz 21 maja 2020 przez Sobczyk Nowicjusz (150 p.)
Miałem na mysli to że uzywając switcha wybiore stworzenie obiektu wydarzenie i na tym zaprzestanę wiec musze uzyc delete jedynie na tym obiekcie jednak w kodzie musze uwzglednić również zwalnianie pamieci obiektów których nie stworze w tej instancji programu.
komentarz 21 maja 2020 przez adrian17 Ekspert (344,860 p.)

zwalnianie pamieci obiektów których nie stworze w tej instancji programu.

Nie, nie musisz przewidzieć zwalniania pamięci programów które zaalokowałeś za tydzień / tydzień temu ;)

W każdym razie, wciąż nie widzę zbytnio problemu.

Alokujesz obiekt -> wrzucasz wskaźnik do vectora -> na koniec robisz delete na wszystkich wskaźnikach w vectorze.

komentarz 21 maja 2020 przez Sobczyk Nowicjusz (150 p.)
Że też nie wpadlem na to że wszystko mam pod ręką w wektorze.

W takim razie biore sie za naprawe kodu.

Bardzo dziekuje za pomoc :)
komentarz 21 maja 2020 przez Sobczyk Nowicjusz (150 p.)

Jeszcze chcialbym sie upewnic czy taka petla spełnia swoj cel i rzeczywiscie nie spowoduje wycieku pamieci

for(int i=0; i<tablica_wydarzen.size(); i++)
      delete tablica_wydarzen[i];

 

komentarz 21 maja 2020 przez adrian17 Ekspert (344,860 p.)

Wygląda OK.

BTW, od lat można pisać prościej:

for (auto wskaznik : tablica_wydarzen)
      delete wskaznik;

 

Podobne pytania

0 głosów
0 odpowiedzi 134 wizyt
pytanie zadane 18 kwietnia 2020 w C# przez Kamilmis Nowicjusz (120 p.)

92,578 zapytań

141,426 odpowiedzi

319,653 komentarzy

61,961 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...