Kopiowanie tablicy obiektów class

0

Witam,

Mam problem, z którym nie mogę sobie poradzić ponieważ go nie rozumiem. Proszę o wskazówki i wyjaśnienie.

Najpierw kod :


#include <cstdlib>
#include <iostream>

using namespace std;

class Kategoria {
public:
    int nr;
    string rodzaj;
    int pozycja;
    int widocznosc;

    void przypiszDane(string r, int p, int w) {
        rodzaj = r;
        pozycja = p;
        widocznosc = w;
    }

    string wypiszDane() {
        return rodzaj;
    }
};

Kategoria *kategoria; // globalny wskaznik na class
int IloKat;                // globalna wartosc

void dodajElement(string nazwa, int nr, int wart);

int main(int argc, char** argv) {

    IloKat = 10;
    kategoria = new Kategoria[IloKat + 1];   // zwiekszam zakres na potrzeby dodania dodatkowego obiektu

    for (int i = 0; i < IloKat; i++) {
        kategoria[i].przypiszDane("test", i, 1);
    }

    dodajElement("test+1", IloKat, 0);
    dodajElement("test+2", IloKat, 0);
    dodajElement("test+3", IloKat, 0);

    return 0;
}

void dodajElement(string nazwa, int nr, int wart) {

    kategoria[IloKat].przypiszDane(nazwa, nr, wart);

    Kategoria *klasa_temp; // tworze tymczasowy wskaznik na clase
    klasa_temp = kategoria;  // przypisuje jej aktualny stan classy kategoria

    delete [] kategoria;
    IloKat++;

    kategoria = new Kategoria[IloKat + 1]; // zwiekszam zakres na potrzeby dodania dodatkowego obiektu
    kategoria = klasa_temp;  //  **

    delete [] klasa_temp;

}

Przy próbie dodania kolejnych elementów program się wysypuje się.

**

Wydaje mi się , że jest to najważniejsza linia kodu. Ja to rozumiem tak , że jeśli mam tablice wypełnioną obiektami od 0 - 10 gdzie zaalocowaną tablice mam new Kategoria[12] to zawsze zostaje 1 "puste" miejsce na dodanie ewentualnego dodatkowego obiektu i później przeallocowanie z powrotem jej do nowej tablicy obiektów powiększonych o 1.
Jednak jak działa przypisanie jednej tablicy obiektów do drugiej? Nie powinna ona wypełnić po prostu zakres np od 0 - 10 a to 11 miejsce zostawić puste na potrzeby dalszego kodu ?

Będę wdzięczny za wyjaśnienia i pomoc.

Pozdrawiam
Jakub

0

Masakra. To co robisz w metodzie dodajElement w ogóle nie ma sensu. Ale po kolei:

    kategoria[IloKat].przypiszDane(nazwa, nr, wart); //to jest ok zakładając że tablica jest o 1 większa

    Kategoria *klasa_temp = kategoria;  // to jest bez sensu, bo ten wskaźnik po wykonaniu delete NIE BĘDZIE wskazywał na nic sensownego!
    delete [] kategoria;

    IloKat++;
    kategoria = new Kategoria[IloKat + 1]; // nic tutaj nie zwiększasz tylko alokujesz NOWY, większy blok pamięci
    kategoria = klasa_temp;  //  horror, gubisz właśnie wskaźnik do nowego bloku pamięci i w jego miejsce przypisujesz wskaźnik który pokazuje cholera wie na co

    delete [] klasa_temp; //horror, robisz delete drugi raz na TYM SAMYM wskaźniku

Może jednak warto DOCZYTAĆ jak działa new i delete a nie pisać "na pałe"? Twój problem polega na tym że nie wiesz że wskaźnik to jest tylko zwykła liczba, nic więcej. To jest numer komórki pamięci pod którym może znajdować się jakaś wartość. Wskaźnik nic więcej nie przechowuje! Jak przypiszesz jeden wskaźnik do drugiego to NIC SIĘ NIE KOPIUJE, tylko sam adres na który było wskazanie.

Jeśli ta tablica ma się tak rozszerzać o 1 to lepiej napisać to na bazie listy a nie tablicy. Jak już musisz mieć tablicę to to musi wyglądać tak:

  • alokujesz nowy, większy blok pamięci
  • PRZEPISUJESZ dane do nowego bloku
  • kasujesz stary blok i nowy blok przypisujesz do swojego wskaźnika

Swoją drogą wiesz ze istnieje coś takiego jak vector<> które realizuje taka funkcjonalność?

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