Forum Gry Hobby Sprzęt Rozmawiamy Archiwum Regulamin

Forum: Program C++ - problem

07.03.2012 20:01
😊
1
pajkul
93
Senator

Program C++ - problem

http://pastebin.com/LatYa3FB

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?

07.03.2012 20:26
2
odpowiedz
zanonimizowany792388
37
Generał

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 ?

07.03.2012 20:45
3
odpowiedz
pajkul
93
Senator

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?

07.03.2012 20:53
4
odpowiedz
zanonimizowany792388
37
Generał

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);

07.03.2012 20:59
5
odpowiedz
pajkul
93
Senator

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);

07.03.2012 21:12
6
odpowiedz
PaWeLoS
168
Admiral

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).

07.03.2012 21:14
Wooler
7
odpowiedz
Wooler
81
Konsul

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]

07.03.2012 21:20
8
odpowiedz
zanonimizowany792388
37
Generał

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]);

07.03.2012 22:08
9
odpowiedz
pajkul
93
Senator

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?

07.03.2012 22:38
10
odpowiedz
PaWeLoS
168
Admiral
Forum: Program C++ - problem