Tworze klase student. Wprowadzam dane, imie, nazwisko, przedmioty itd.
Mam pytanie odnośnie linijki 109. Jedna ze zmiennych skladowych klasy jest wskaznik typu string (wskPrzedmioty). Utworzylem za jego pomoca dynamiczna tablice o liczbie elementow rownej liczbie przedmiotow w taki sposob:
wskPrzedmioty = new string[Ile];
Wiec powinienem byc w stanie odnosic sie do poszczegolnych komórek tablicy stringow w sposob taki jak w przypadku tablic, czyli wskPrzedmioty[0], wskPrzedmioty[1] itd...
Jednak tak robic nie moge. Nie moge przypisac zadnego napisu do takiej komórki w tej tablicy. Dlaczego?
Upewnij sie ze nie wywolujesz domyslnego konstruktora bo wtedy w tablicy wskPrzedmioty nie ma miejsca na jakiekolwiek dane. Staraj sie uzywac ifow sprawdzajacych stan obiektow, opcjonalnie uzywaj wyjatkow(try, catch).
Debugerem sprawdzaj kazda czesc programu ktora moze powodowac bledy.
Przy probie przypisania wartosci do wskPrzedmioty zostanie wywolany call stack, tam mozesz zobaczyc co wywolalo blad, cofnac sie do kodu wywolywanego przed bledem.
Dlaczego nie uzywasz gotowych kontenerow, np std::vector ?
Mozna bardziej po polsku? :)
Upewnij sie ze nie wywolujesz domyslnego konstruktora bo wtedy w tablicy wskPrzedmioty nie ma miejsca na jakiekolwiek dane.
Co to znaczy?
Czyli nie tworz obiektu z klasy student w ten sposob:
student stu;
student stu();
student *stu=news student();
Jesli wywolasz domyslny konstruktor w ten sposob utworzysz tablice zerowa - wskPrzedmioty = new string[0]; , a moze to poprostu to literowka, i chciales alokowac 10 elementow ?
Program zadziala jesli wywolasz drugi konstruktor:
student *stu=new student(6);
Zamiast tego:
student* studentwsk = new student[k]; linijka 78
napisac tak?:
student* studentwsk = new student(k);
Odnosnie tego, tak, tutaj ma byc string[0]. Tzn nie wiem w ogole po co taki konstruktor komu potrzebny, nie rozumiem tego, ale ktos mi tak podpowiedzial. To po co mi on jest w ogole potrzebny?
student::student()
‹
Ilosc_przedmiotow=0;
wskPrzedmioty = new string[0];
›
A tak w ogole, to rzeczywiscie mimo ze poczatkowe obiekty student maja tablice zerową, to w linii 95. ja to zmieniam - zwiekszam tablice w zaleznosci od zyczenia uzytkownika.
studentwsk[nr]=student(b);
Hmm... problem w Twoim programie jest dużo bardziej złożony, niż by się mogło wydawać.
Masz dwa wyjścia:
- albo używasz zamiast wszystkich tablic klasy standardowej vector (polecam to rozwiązanie :) )
- albo uczysz się o konstruktorach kopiujących, destruktorach i operatorach przypisania, co to jest (pewnie się domyślasz), ale przede wszystkim po co to się używa.
edit. Chociaż wróć, o konstruktorach kopiujących, destruktorach i operatorach przypisania i tak będziesz się musiał pouczyć :)
Ogólnie się wszystko rozchodzi o tę linijkę:
studentwsk[nr]=student(b);
A jak w tym miejscu:
student* studentwsk = new student[k];
napiszesz tak:
student* studentwsk = new student(k);
to utworzysz tylko jeden obiekt, a nie tablicę.
Hmm... destruktor to Ty masz, to fajnie :)
Jeszcze tylko konstruktor kopiujący, i operator przypisania (to w szczególności w Twoim przypadku).
Może spróbuj (nazwastringa)[indeks] (chodzi o nazwę w nawiasie)?
[edit] to chyba nie problem. Myślałem, że może być problem ze względu na to, że istnieje dla stringa także operatorowa funkcja [] która zwraca literę podaną jako indeks. Ale przecież przy wskaźniku aby dostać się do tej funkcji, trzeba by pewnie napisać coś w stylu (nazwastringa[nr_el_tablicy])[nr_litery]
Jak chcesz stworzyc tablice nie uzywajac domyslnego konstruktora to robisz tak:
najszybciej dla tablicy dynamicznej ktorej nie znasz ilosci uzywanych elementow:
std::vector<student> students(12, student(6));
dla tablicy z gory przypisana iloscia elementow:
student students[12]=‹student(6), student(6), student(6),student(6), student(6), student(6), student(6), student(6), student(6), student(6), student(6), student(6)›;
gdzie 12 to ilosc studentow, 6 to ilosc przedmiotow dla kazdego studenta. Potem students uzywasz jako normalnej tablicy przy czym nie musisz jej zwalniac przy wychodzeniu z programu. Jedynie w destruktorze student usuwasz wszelkie alokacje pamieci.
A tak w ogole, to rzeczywiscie mimo ze poczatkowe obiekty student maja tablice zerową, to w linii 95. ja to zmieniam - zwiekszam tablice w zaleznosci od zyczenia uzytkownika.
studentwsk[nr]=student(b);
Tworzenie zerowej tablicy jest zbedne, i tak przy deklaracji nie ma zadnych elementow.
Mozesz takze stworzyc tablice students z domyslnym konstruktorem ale ilosc przedmiotow ustawic inna metoda juz po stworzeniu tablicy "przelatujac" kazdego studenta ;-]:
student *students=new student[12];
for(int k=0;k<12;k++)
students[k].ustawIloscPrzedm(6);
lub
students[k].ustawIloscPrzedm(iloscPrzedm[k]);
Błagam o pomoc...
Czy ktos moglby mi pomoc w zrobieniu tego konstruktora kopiujacego i operatora przypisania, jesli to oczywiscie jest konieczne? Nie ogarniam juz. Siedze od rana nad tym... Nie musi to byc na teraz, ale powiedzmy w ciagu najblizszych kilkunastu godzin.
Czyli najlatwiej byloby mi usunac z konstruktora to tworzenie zerowej tablicy dynamicznej, tylko najpierw utworzyc obiekt ze wskaznikiem wskPrzedmioty ustawionym na cos losowego, a potem dopiero osobna funkcja z tej klasy ustalac dynamiczna tablice dla obiektu?