kt1117 Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 Ostatnio uczę się obiektowości w C++ i napisałem program, który losuje liczby nie powtarzając się w obiektowości. I napotkałem dziwną sytuację. Zrobiłem konstruktor, tam wyzerowałem wszystkie zmienne, wypytałem się użytkownika o liczby i wywołałem inną metodę. W tej metodzie odwołałem się zmiennych, które przypisałem w konstruktorze, pytając się usera o liczby. I tu patrzę, a metoda wywala mi wartości z kosmosu, znaczy nie wyzerowana. I tu moje pytanie, jaki zakres ma zmienna w klasie? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 podaj kod Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 11 Marca 2011 Autor Udostępnij Opublikowano 11 Marca 2011 #include <iostream> #include <cstdlib> #include <ctime> using namespace std; class losowanie { int wylosowane[8]; int podane[10]; int a; int b; public: void wylosowywanie(); losowanie(); ~losowanie(); }; losowanie::losowanie() { srand(time(0)); a=0; b=0; losowanie::wylosowywanie(); }; void losowanie::wylosowywanie() { cout<<"Podaj 10 liczb: "<<endl; cin>>podane[0]>>podane[1]>>podane[2]>>podane[3]>>podane[4]>>podane[5]>>podane[6]>>podane[7]>>podane[8]>>podane[9]; do { do { a=((rand())%11)-1; a=losowanie::podane[a]; } while (a==wylosowane[0] or a==wylosowane[1] or a==wylosowane[2] or a==wylosowane[3] or a==wylosowane[4] or a==wylosowane[5] or a==wylosowane[6] or a==wylosowane[7]); wylosowane[b]=a; b++; } while (b<10); }; losowanie::~losowanie() { cout<<"Liczby to:"<<wylosowane[0]<<", "<<wylosowane[1]<<", "<<wylosowane[2]<<", "<<wylosowane[3]<<", "<<wylosowane[4]<<", "<<wylosowane[5]<<", "<<wylosowane[6]<<", "<<wylosowane[7]<<"."<<endl; }; int main() { losowanie::losowanie(); return 0; } Ten kod działa, zaraz dam ten poprzedni, tylko muszę go odtworzyć. E: Ten dziwny: #include <iostream> #include <cstdlib> #include <ctime> using namespace std; class losowanie { int wylosowane[8]; int podane[10]; int a; int b; public: void wylosowywanie(); losowanie(); ~losowanie(); }; losowanie::losowanie() { srand(time(0)); a=0; b=0; int wylosowane[8]={0,0,0,0,0,0,0,0}; int podane[10]={0,0,0,0,0,0,0,0,0,0}; cout<<"Podaj 10 liczb: "; cin>>podane[0]>>podane[1]>>podane[2]>>podane[3]>>podane[4]>>podane[5]>>podane[6]>>podane[7]>>podane[8]>>podane[9]; losowanie::wylosowywanie(); }; void losowanie::wylosowywanie() { do { do { a=((rand())%11)-1; a=losowanie::podane[a]; } while (a==wylosowane[0] or a==wylosowane[1] or a==wylosowane[2] or a==wylosowane[3] or a==wylosowane[4] or a==wylosowane[5] or a==wylosowane[6] or a==wylosowane[7]); wylosowane[b]=a; b++; } while (b<10); }; losowanie::~losowanie() { cout<<"Liczby to:"<<wylosowane[0]<<", "<<wylosowane[1]<<", "<<wylosowane[2]<<", "<<wylosowane[3]<<", "<<wylosowane[4]<<", "<<wylosowane[5]<<", "<<wylosowane[6]<<", "<<wylosowane[7]<<"."<<endl; }; int main() { losowanie * obiekt=new losowanie; delete obiekt; return 0; } I ten, który według mnie powinien działać a wywala błąd: w\losowanie\main.cpp||In constructor 'losowanie::losowanie()':| w\losowanie\main.cpp|24|warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x| w\losowanie\main.cpp|24|error: cannot convert '<brace-enclosed initializer list>' to 'int' in assignment| w\losowanie\main.cpp|25|warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x| w\losowanie\main.cpp|25|error: cannot convert '<brace-enclosed initializer list>' to 'int' in assignment| ||=== Build finished: 2 errors, 2 warnings ===| , #include <iostream> #include <cstdlib> #include <ctime> using namespace std; class losowanie { int wylosowane[8]; int podane[10]; int a; int b; public: void wylosowywanie(); losowanie(); ~losowanie(); }; losowanie::losowanie() { srand(time(0)); a=0; b=0; wylosowane[8]={0,0,0,0,0,0,0,0}; podane[10]={0,0,0,0,0,0,0,0,0,0}; cout<<"Podaj 10 liczb: "; cin>>podane[0]>>podane[1]>>podane[2]>>podane[3]>>podane[4]>>podane[5]>>podane[6]>>podane[7]>>podane[8]>>podane[9]; losowanie::wylosowywanie(); }; void losowanie::wylosowywanie() { do { do { a=((rand())%11)-1; a=losowanie::podane[a]; } while (a==wylosowane[0] or a==wylosowane[1] or a==wylosowane[2] or a==wylosowane[3] or a==wylosowane[4] or a==wylosowane[5] or a==wylosowane[6] or a==wylosowane[7]); wylosowane[b]=a; b++; } while (b<10); }; losowanie::~losowanie() { cout<<"Liczby to:"<<wylosowane[0]<<", "<<wylosowane[1]<<", "<<wylosowane[2]<<", "<<wylosowane[3]<<", "<<wylosowane[4]<<", "<<wylosowane[5]<<", "<<wylosowane[6]<<", "<<wylosowane[7]<<"."<<endl; }; int main() { losowanie * obiekt=new losowanie; delete obiekt; return 0; } Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 nie wywołuje sie konstruktora ot tak, musisz stworzyć obiekt, a potem go skasować: losowanie* los = new losowanie(); delete los; Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 11 Marca 2011 Autor Udostępnij Opublikowano 11 Marca 2011 To mnie w kursie okłamali, ale dalej konstruktor nie zmienia/ zmienia zbyt późno wartość wymienionych zmiennych, i dlaczego muszę jeszcze raz deklarować zmienne, które zadeklarowałem w definicji klasy? E: Teraz mam w miarę logiczny (wg. mnie) i działa: #include <iostream> #include <cstdlib> #include <ctime> using namespace std; class losowanie { int wylosowane[8]; int podane[10]; int a; int b; public: void wylosowywanie(); losowanie(); ~losowanie(); }; losowanie::losowanie() { srand(time(0)); a=0; b=0; cout<<"Podaj 10 liczb: "<<endl; cin>>podane[0]>>podane[1]>>podane[2]>>podane[3]>>podane[4]>>podane[5]>>podane[6]>>podane[7]>>podane[8]>>podane[9]; losowanie::wylosowywanie(); }; void losowanie::wylosowywanie() { do { do { a=((rand())%11)-1; a=losowanie::podane[a]; } while (a==wylosowane[0] or a==wylosowane[1] or a==wylosowane[2] or a==wylosowane[3] or a==wylosowane[4] or a==wylosowane[5] or a==wylosowane[6] or a==wylosowane[7]); wylosowane[b]=a; b++; } while (b<10); }; losowanie::~losowanie() { cout<<"Liczby to:"<<wylosowane[0]<<", "<<wylosowane[1]<<", "<<wylosowane[2]<<", "<<wylosowane[3]<<", "<<wylosowane[4]<<", "<<wylosowane[5]<<", "<<wylosowane[6]<<", "<<wylosowane[7]<<"."<<endl; }; int main() { losowanie*los=new losowanie(); delete los; return 0; } Tylko nie wiem jak wyzerować tablice, bo widocznie zapis array[n]={a,b,c,......,m} działa tylko przy deklaracji, a nie można nadać wartości zmiennej w deklaracji klasy, tzn. że muszę zerować każdą komórkę osobno? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Konrad-GM Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 Listę inicjalizacji można użyć tylko w czasie tworzenia obiektu (deklaracja) int a[]={1,2,3}; // Dobrze int a[3]; a={1,2,3}; // Źle dla wyzerowania użyj "memset" @YXE, głupoty piszesz, nie trzeba używać 'new', aby wywołać konstruktor :) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 skoro chce, by zmienne miały zasięg obiektu, to przecież musi on istnieć. sam głupoty gadasz. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 11 Marca 2011 Autor Udostępnij Opublikowano 11 Marca 2011 A jakie ma parametry i w jakiej bibliotece się znajduje? (memset) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Konrad-GM Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 Wystarczy losowanie(); E: biblioteka standardowa memset(void* dest, int val, int size); Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 11 Marca 2011 Autor Udostępnij Opublikowano 11 Marca 2011 Czyli nie trzeba pisać losowanie: :( ...), nawet poza blokami funkcji zadeklarowanych w obiektach? E: Wyskakuje, że nie zadeklarowana, ale mniejsza z tym, jakoś sobie poradzę bez tego. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Konrad-GM Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 http://www.cplusplus.com/reference/clibrary/cstring/memset/ , tutaj masz opisane działanie memset, a także wymagany header Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 11 Marca 2011 Autor Udostępnij Opublikowano 11 Marca 2011 Dzięki, działa. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 Listę inicjalizacji można użyć tylko w czasie tworzenia obiektu (deklaracja) Wiesz co to jest deklaracja? ;) Czyli nie trzeba pisać losowanie: :( ...), nawet poza blokami funkcji zadeklarowanych w obiektach? W metodach danej klasy przy odwoływaniu się do funkcji, która także jest metodą(tej samej klasy) nie musisz się bawić w takie pierdoły. Do dyspozycji jest wskaźnik this, który załatwia takie sprawy. Przy samym konstruktorze inicjuj składniki klasy: class Test { Test():k(0) { } private: int k; }; Jest to znacznie szybsze. Listę inicjalizacji można użyć tylko w czasie tworzenia obiektu Można użyć tylko dla typów wbudowanych i pod'ów a nie obiektów. nie wywołuje sie konstruktora ot tak, musisz stworzyć obiekt, a potem go skasować: Przecież tworzy obiekt? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 11 Marca 2011 Autor Udostępnij Opublikowano 11 Marca 2011 Przedtem żeby zaoszczędzić linijkę kodu dałem po prostu: losowanie::losowanie(); E:A jak mam więcej zmiennych to czym je oddzielam? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 Przykład: WindowMgr():Singleton<WindowMgr>(),m_uWndCount(0),m_bExit(false), m_pNetworkObject(0) { } Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 11 Marca 2011 Autor Udostępnij Opublikowano 11 Marca 2011 I wtedy całe ciało konstruktora w definicji klasy, czy robić obok? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 Jak wolisz: class T { T():k(0){} private: int k; }; lub class T { T(); private: int k; }; T::T():k(0){} Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 11 Marca 2011 Autor Udostępnij Opublikowano 11 Marca 2011 A wydajność taka sama? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 11 Marca 2011 Udostępnij Opublikowano 11 Marca 2011 Znacznie lepsza, szczególnie dla złożonych typow. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 13 Marca 2011 Autor Udostępnij Opublikowano 13 Marca 2011 Czyli będę robić osobno deklaracje i definicje, dzięki. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 13 Marca 2011 Udostępnij Opublikowano 13 Marca 2011 Chodziło mi o wydajność między: class T { T():k(costam){} private: int k; }; a class T { T(){k=costam;} private: int k; }; Chociaż w przypadku klas i tak rób osobno deklaracje/definicje. Klasa -> plik deklaracje Klasa.h + definicje Klasa.cpp Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 13 Marca 2011 Autor Udostępnij Opublikowano 13 Marca 2011 Aha, ostatnio mi dzielenie pliku nie wychodziło, bo wrzuciłem definicje do .cpp i cały czas wywalało błąd, że wcześniej zadeklarowano tutaj i pokazywało tą samą linijkę, w której wystąpił błąd. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Konrad-GM Opublikowano 13 Marca 2011 Udostępnij Opublikowano 13 Marca 2011 Zapomniałeś o include guardach :) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kt1117 Opublikowano 13 Marca 2011 Autor Udostępnij Opublikowano 13 Marca 2011 To są te ifdef, i endef? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Konrad-GM Opublikowano 13 Marca 2011 Udostępnij Opublikowano 13 Marca 2011 Tak #ifndef _HEADER_FILE_H_ #define _HEADER_FILE_H_ // Code #endif Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się