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

Dynamiczne tworzenie innego obiektu w obiekcie c++

Object Storage Arubacloud
0 głosów
1,210 wizyt
pytanie zadane 1 grudnia 2017 w C i C++ przez chacken Użytkownik (820 p.)

Uprościłem zadanie do minimum tj. napisałem nowy prosty kod, żeby było czysto i prosto z ewentualną pomocą:
Mam klasę która tworzy pojazd:
 

class Pojazd{
    string nazwa;
    public:
    Pojazd(){
        nazwa = "Domyslny";
    }
    Pojazd(string name){
    nazwa = name;
    }
    void wypisz(){
    cout << nazwa << endl;
    }
};

Następnie mam klase sklep która ma pole typu Pojazd oraz pole ilość_ofert informujące o tym ile samochodów jest w tym obiekcie:
 

class Sklep{
    int liczba_ofert = 0;
    Pojazd *w = new Pojazd[liczba_ofert];

public:
    void dodaj_do_oferty(Pojazd &a){
        liczba_ofert++;
        w[liczba_ofert-1] = a;
        
    }
    void wypisz_oferty(){
        for (int i = 0; i < liczba_ofert; ++i) {
            w[i].wypisz();
        }
    }
};

Oraz main który mi to wykonuje:
 

int main() {
    Pojazd toyota("toyota");
    Pojazd suzuki("suzuki");
    Pojazd hundai("hundai");

    Sklep skl;
    skl.dodaj_do_oferty(toyota);
    skl.dodaj_do_oferty(suzuki);
    skl.wypisz_oferty();

    return 0;
}

No i mi to nie działa.... nie wiem dlaczego te dynamiczne alokowanie obiektu Pojazd *w = new Pojazd[liczba_ofert] gdy zwiększy się liczba ofert nie działa.... zrobiłem dokładnie taki sam przykład tylko że zamiast "Pojazd" jest int... i działa normalnie:
 

class Zbior{
    int *dane;
    int rozmiar = 0;
public:
    Zbior(){
        dane = new int[rozmiar];
    }
    void dodaj(int a){
        dane[rozmiar] = a;
        rozmiar++;
    };
 
int main(){
Zbior x;
x.dodaj(1);
x.dodaj(2);
x.dodaj(6);
/// wszystko działa pięknie
}

Jak to zrobić? Ja chyba czegoś nie rozumiem tutaj ;/


Ogólnie zadanie to tej konkretnej klasy Sklep brzmi tak:


"Napisz klasę Pojazd która (..... XYZ ....)" Następnie:
"Napisz klasę Sklep, która zawiera prywatne pola:
• wskaźnik na dane (oferowane pojazdy),
• liczba oferowanych pojazdów.
oraz metody: 3
• wypiszOferte() - metoda wypisuje wszystkie oferowane samochody,
• dodajSamochod(Pojazd &a) - dodaje nowy samochod do oferty,
• przejmijKonkurencje(SalonSamochodowy&) - łączy zawartośc obu obiektow

 

Jak już zrozumiem jak to działa to z łączeniem nie będzie problemów ale nie mam pojęcia dlaczego dostaję Segmentation Error.... jak przy dokładnie takim samym przykładzie z intem mi działa ;/

Z tego co rozumiem to to musi być dynamiczne... dlatego mamy "liczbę oferowanych pojazdów" która będzie odpowiadać za wielkość tablicy którą jest zmienna Pojazd *dane....

Taki trick -> jak wpisze na starcie do zmiennej "liczba_ofert" jakaś większą liczbę ofert to normalnie będzie działać.... kurde co tam się dzieje? :(

komentarz 1 grudnia 2017 przez chacken Użytkownik (820 p.)
przeniesione 1 grudnia 2017 przez draghan

Dodam jeszcze że próbowałem w taki sposób też:
 

class Sklep{
    int liczba_ofert = 0;
    Pojazd *w;

public:
        void dodaj_do_oferty(Pojazd &a){
                w = new Pojazd[liczba_ofert];
                liczba_ofert++;
                w[liczba_ofert-1] = a;
            }

Tak żeby za każdym razem tworzył odpowiednią wielkość obiektu.... ale ostatecznie i tak crashuje ;/ a jak chcę wypisać poprzedni produkt to go znaleźć nie może 

komentarz 2 grudnia 2017 przez j23 Mędrzec (194,920 p.)

Zamiast bawić się z new[]/delete[], użyj std::vector.

1 odpowiedź

0 głosów
odpowiedź 1 grudnia 2017 przez amb00 Bywalec (2,000 p.)
Na samym początku alokujesz pamięć równą zero, a zrobienie tego jest niemożliwe. Poza tym ten kod jest bezsensu, nie uwzględniłeś w ogóle zwalniania przydzielonej pamięci w destruktorze, w dodatku za każdym razem po wywołaniu metody dodaj_do_oferty tracisz dotychczasowe dane ze wskaźnika Pojazd *w, gdyż za każdym razem dostajesz po wywołaniu new do dyspozycji nowy blok pamięci, a poprzedni tracisz. To też powoduje wyciek pamięci. Zapytaj się nauczyciela/wykładowcy, który Ci to zadał czy mógłbyś użyć vectora do zrobienia tego, jeśli nie będziesz mógł, to za każdym razem będziesz musiał realokować pamięć na tym wskaźniku.
komentarz 2 grudnia 2017 przez j23 Mędrzec (194,920 p.)

a zrobienie tego jest niemożliwe.

Akurat to jest możliwe ;) new T[0] zwróci poprawny wskaźnik, który powinieneś później usunąć.

Podobne pytania

0 głosów
2 odpowiedzi 154 wizyt
pytanie zadane 9 kwietnia 2016 w C i C++ przez Klik Obywatel (1,540 p.)
0 głosów
2 odpowiedzi 514 wizyt
pytanie zadane 30 listopada 2017 w C i C++ przez chacken Użytkownik (820 p.)
0 głosów
1 odpowiedź 864 wizyt

92,555 zapytań

141,404 odpowiedzi

319,557 komentarzy

61,940 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!

...