RaistlinBlackRobe Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 Witam. Ostatnio pojawił się u mnie pewien problem, którego pomimo usilnych starań nie udało mi się rozwiązać. Błędy, które się pojawiły kompletnie mnie zaskoczyły. Sprawa wygląda następująco: Mam w projekcie 3 pliki: main.cpp, main.h, obj.h main.cpp: #include "main.h" #include "obj.h" bool init=1; obj_hero* inst_hero = new obj_hero; obj_block* inst_block[2]; //tworzymy tablicę wskaźników na klasę obj_block int inst_block_count = 2; //zmienna przechowująca ilość elementów danej tablicy int g_main() { if (init) //instrukcje tworzenia instancji { unsigned x_rand; unsigned y_rand; for(int i=0; i<inst_block_count; i++) { inst_block[i]= new obj_block; srand(time(NULL)); do { x_rand=floor(rand()%32); y_rand=32 - ceil(rand()%32); } while(grid_state[x_rand][y_rand]!=GRID_FREE); inst_block[i]->x_grid=x_rand; inst_block[i]->x=inst_block->x_grid+0.5*inst_block->a; inst_block[i]->y_grid=y_rand; inst_block[i]->y=inst_block->y_grid+0.5*inst_block->a; grid_state[x_rand][y_rand]=GRID_BLOCK; }; init=0; }; //w tym miejscu ustawianie kamery i eventy return 0; }; Tytułem wyjaśnienia: -funkcja g_main() jest funkcją, której prototyp znajduje się w main.h i jest wywoływana w głównej pętli -grid_state[][] to tablica enumów, określa co się znajduje na danym polu main.h: W nim znajdują się #includy, deklaracje zmiennych globalnych, definicje procedury okienkowej i WinMaina. obj.h: Tutaj mam definicje wszystkich klas i ich metod. Komunikaty błędów: 'srand' undeclared (first use this function) 'rand' undeclared (first use this function) 'ceil' undeclared (first use this function) 'floor' undeclared (first use this function) 'x_grid' has not been declared request for member of non-aggregate type befor '+' token i jeszcze szereg takich samych błędów dotyczących kolejnych zmiennych... Czy ktoś może wie, co zrobiłem nieprawidłowo? Zaznaczam, że odpowiednie nagłówki dodałem. Z góry dzięki. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 po pierwsze to nie zainkludowałeś biblioteki math.h. w ogóle coś nie teges to wygląda, zrobię sobie herbatę i dopisze zaraz co mam na mysli ;) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
RaistlinBlackRobe Opublikowano 13 Listopada 2009 Autor Udostępnij Opublikowano 13 Listopada 2009 po pierwsze to nie zainkludowałeś biblioteki math.h. w ogóle coś nie teges to wygląda, zrobię sobie herbatę i dopisze zaraz co mam na mysli ;) Zarówno math.h, jak i ctime są dodane w main.h. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 w takim razie podaj dokladna tresc bledow, tj. ze sciezka wzgledna do plikow, bo albo masz gdzies wczesniej uzyte te funkcje niz zainkludowales ich biblioteki albo masz kilka plikow cpp i nie kazdemu inkludujesz. Swoja droga, opisz mniej wiecej jak dziala Twoj program (opisowo co sie dzieje po kolei) bo mam pare rozwiazan ktore oducza Cie zlych nawykow ;p Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
RaistlinBlackRobe Opublikowano 13 Listopada 2009 Autor Udostępnij Opublikowano 13 Listopada 2009 Błedy wyskakują w pliku main.cpp, w funkcji g_main(), w środku konstrukcji warunkowej if (init), czyli odnoszą się do właśnie tych instrukcji tworzenia objektów i przypisywania ich polom pewnych wartości. Odwoływanie się do konkretnej linijki nie ma sensu, bo wyciąłem i wkleiłem tutaj to co trzeba było. Jak już zaznaczyłem funkcja g_main() jest wywoływana w środku pętli głównej programu, w nagłówku main.h w funkcji WinMain(), a includy są naturalnie wcześniej. EDIT: Mam jeden plik .cpp. Działanie funkcji g_main(): -Przy pierwszym obiegu pętli wypełnia tablice wskaźników świeżutkimi objektami i (jeśli trzeba to zrobić tu) nadaje im wartości początkowe. -Wykonuje metodę event_step() każdej instancji która ją posiada. Zbieżności nazw z gmowymi nieprzypadkowe. -glClear(...); -glEnable(GL_DEPTH_TEST); -Ustawienia kamery za pomocą gluLookAt(...); -Rysowanie podłoża. -Wykonuje metodę event_draw() każdej instancji. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 a czy srand nie jest przypadkiem z stdlib? zapodaj jakie includy masz Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
RaistlinBlackRobe Opublikowano 13 Listopada 2009 Autor Udostępnij Opublikowano 13 Listopada 2009 #define WIN32_LEAN_AND_MEAN #include <windows.h> //nagłówek windows #include <gl/glaux.h> #include <ctime> #include <math.h> srand() i rand() są z <ctime>, przynajmniej dotychczas tak ich używałem. Moja edycja minęła się z twoim postem, więc umieszczam ponownie opis działania: -Przy pierwszym obiegu pętli wypełnia tablice wskaźników świeżutkimi objektami i (jeśli trzeba to zrobić tu) nadaje im wartości początkowe. -Wykonuje metodę event_step() każdej instancji która ją posiada. Zbieżności nazw z gmowymi nieprzypadkowe. -glClear(...); -glEnable(GL_DEPTH_TEST); -Ustawienia kamery za pomocą gluLookAt(...); -Rysowanie podłoża. -Wykonuje metodę event_draw() każdej instancji. EDYCJA: Na <cstdlib>ie poszły te funkcje. To uczyniło teraz problem już stricte dotyczący tworzenia instancji. Rzecz w tym, że dalej nie potrafi się odwołać do pól tych objektów i wygląda to tak, jak gdyby nie zostały one stworzone. inst_block[i]= new obj_block; Czy ta linijka jest źle napisana? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 zalezy. podaj definicje klasy obj_block Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
RaistlinBlackRobe Opublikowano 13 Listopada 2009 Autor Udostępnij Opublikowano 13 Listopada 2009 Definicja klasy: class obj_block //klasa objektu przeszkody { public: float x; float y; int x_grid; //kratka x, w której się znajduje int y_grid; //kratka y, w której się znajduje int z; float a; //długość boku float h; //wysokość obj_block(); //konstruktor int event_draw(); //rysowanie objektu }; obj_block::obj_block(): x (4.0f), y (4.0f), x_grid (0), y_grid (0), z (0.0f), a (8.0f), h (8.0f) { }; int obj_block::event_draw() { glPushMatrix(); glTranslatef(x, y, z+0.5*h); glRotatef(0.0f, 1.0f, 1.0f, 1.0f); //ustawiamy obrót na jego brak glBegin(GL_QUADS); //rysujemy 6 ścian glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f*a, -0.5f*a, -0.5f*h); //-z glColor3f(0.75f, 0.25f, 0.0f); glVertex3f(0.5f*a, -0.5f*a, -0.5f*h); glColor3f(0.75f, 0.0f, 0.0f); glVertex3f(0.5f*a, 0.5f*a, -0.5f*h); glColor3f(0.5f, 0.5f, 0.0f); glVertex3f(-0.5f*a, 0.5f*a, -0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f*a, -0.5f*a, 0.5f*h); //z glColor3f(0.75f, 0.25f, 0.0f); glVertex3f(0.5f*a, -0.5f*a, 0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.5f*a, 0.5f*a, 0.5f*h); glColor3f(0.5f, 0.5f, 0.0f); glVertex3f(-0.5f*a, 0.5f*a, 0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.5f*a, 0.5f*a, -0.5f*h); //x glColor3f(0.75f, 0.25f, 0.0f); glVertex3f(0.5f*a, -0.5f*a, -0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.5f*a, -0.5f*a, 0.5f*h); glColor3f(0.5f, 0.5f, 0.0f); glVertex3f(0.5f*a, 0.5f*a, 0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f*a, 0.5f*a, -0.5f*h); //-x glColor3f(0.75f, 0.25f, 0.0f); glVertex3f(-0.5f*a, -0.5f*a, -0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f*a, -0.5f*a, 0.5f*h); glColor3f(0.5f, 0.5f, 0.0f); glVertex3f(-0.5f*a, 0.5f*a, 0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.5f*a, 0.5f*a, -0.5f*h); //y glColor3f(0.75f, 0.25f, 0.0f); glVertex3f(-0.5f*a, 0.5f*a, -0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f*a, 0.5f*a, 0.5f*h); glColor3f(0.5f, 0.5f, 0.0f); glVertex3f(0.5f*a, 0.5f*a, 0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.5f*a, -0.5f*a, -0.5f*h); //-y glColor3f(0.75f, 0.25f, 0.0f); glVertex3f(-0.5f*a, -0.5f*a, -0.5f*h); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f*a, -0.5f*a, 0.5f*h); glColor3f(0.5f, 0.5f, 0.0f); glVertex3f(0.5f*a, -0.5f*a, 0.5f*h); glEnd(); //kończymy rysować glPopMatrix(); return 0; }; Deklaracja tablicy inst_block: obj_block* inst_block[2]; Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 Boże człowieku co to za potwór ;D Czy mógłbyś podać treść błędu? Nie byłem na ostatnich zajęciach wróżenia z deklaracji ;( Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 hmm, nader dziwne. skoro masz tylko 1 plik cpp i definicje g_main() po definicji klasy obj_block to musi dzialac. na sucho raczej nie pomoge, za duzo niewiadomych. zapodaj projekt jak mozesz na pw, sprawdze na zywo co nie gra. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 hmm, nader dziwne. skoro masz tylko 1 plik cpp i definicje g_main() po definicji klasy obj_block to musi dzialac. na sucho raczej nie pomoge, za duzo niewiadomych. zapodaj projekt jak mozesz na pw, sprawdze na zywo co nie gra. Sęk w tym, że jak ma się czegoś nauczyć to takie praktyki raczej nie są dobrym rozwiązaniem. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 zwykle poza sprawdzaniem tlumacze tez co jest zle wiec jednak sie czegos nauczy ;p Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
RaistlinBlackRobe Opublikowano 13 Listopada 2009 Autor Udostępnij Opublikowano 13 Listopada 2009 Link Nie bijcie za nawiązania do gmowych nazw. Tak mi jakoś wygodnie i wiem, co do czego jest. xD @Will: Wierz mi, że sam wolałbym, to rozwiązać po prostu dzięki wskazówkom, ale i z tego wyciągnę wnioski. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 łojć. ale wiedz że nie każdy ma te same biblioteki co Ty, chodzi o to że muszę to (spróbować) skompilować, aby dostać błędy, a tak to niewiele mogę :P Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 Masz paskudny styl pisania. Polecam przeczytać jakąkolwiek książkę o c++ lub programowaniu obiektowym. W przeciwnym wypadku już przy kodzie 2k+ będziesz miał armagedon. No i podawaj treść błędów i jak już dajesz kod do poprawy dawaj cały projekt. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
RaistlinBlackRobe Opublikowano 13 Listopada 2009 Autor Udostępnij Opublikowano 13 Listopada 2009 No tak biblioteki. Wybaczcie. Linkuję te: -libopengl32.a -libglu32.a -libglaux.a @Will: Wprawdzie przytaczałem je już, ale zrobię to ponownie: 'x_grid' has not been declared request for member of non-aggregate type before '+' token `a' has not been declared request for member of non-aggregate type before ';' token `y_grid' has not been declared request for member of non-aggregate type before '+' token `a' has not been declared request for member of non-aggregate type before ';' token Co dokładnie w moim pisaniu jest paskudne(jezeli chodzi o pisanie ręczne to się zgadzam)? Wiesz, to pewnie w dużej mierze zależy od osoby. Dla mnie akurat taki styl jest przejrzystszy od innych(np. nie lubię bardzo nazw funkcji, w których kolejne wyrazy są oddzielone dużą literą, podkreślenie jest dużo czytelniejsze). Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 13 Listopada 2009 Udostępnij Opublikowano 13 Listopada 2009 Przykładowa klasa: /** */ class WindowMgr:public Singleton<WindowMgr> { public: /** */ inline wID addWindow(RenderWindow* pWnd); /** */ inline void removeWindow(RenderWindow* pWnd); /** */ inline void removeWindow(const std::string& sName); /** */ inline void removeWindow(wID id); /** */ inline void addWindowEventListener(RenderWindow* pWnd,WindowEventListener* pListener); /** */ inline void addWindowKeyboardListener(RenderWindow* pWnd,WindowKeyboardListener* pListener); /** */ inline void addWindowMouseListener(RenderWindow* pWnd,WindowMouseListener* pListener); /** */ void messagePump(); /** */ LRESULT WndProcedure(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam); /** */ void removeAllWndBut(RenderWindow* pWnd); /** */ void removeAll(); /** */ inline uint GetWndCount() const; /** */ WNDPROC GetWndProc() const; private: /*###########################################*/ /* inner class */ class WndHolder { public: // WndHolder(RenderWindow* Wnd); // ~WndHolder(); RenderWindow* pWnd; std::list<WindowEventListener*> m_WndEvents; std::list<WindowKeyboardListener*> m_KeyboardEvents; std::list<WindowMouseListener*> m_MouseEvents; // wMouseState m_MouseState; static bool Compare(const WndHolder holder,const RenderWindow* pWnd); /* */ bool operator==(const RenderWindow* pWnd); }; /*#############################################*/ std::vector<WndHolder> m_vWindows; /* */ inline WndHolder* FindHolder(RenderWindow* pWnd); /* */ inline WndHolder* FindHolder(HWND hwnd); }; /*--------------------------------------------------------------------------------------------------------- WindowMgr::FindHolder() ----------------------------------------------------------------------------------------------------------*/ WindowMgr::WndHolder* WindowMgr::FindHolder(HWND hwnd) { std::vector<WndHolder>::iterator it=m_vWindows.begin(); while(it!=m_vWindows.end()) { if(it->pWnd->GetHandle()==hwnd)return &(*it); ++it; } return NULL; } Przede wszystkim wiesz po co są klasy? Używasz ich jak pojemników to nie C. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
RaistlinBlackRobe Opublikowano 13 Listopada 2009 Autor Udostępnij Opublikowano 13 Listopada 2009 No cóż. Jednym z podstawowych elementów składających się na moje cele, tudzież sposoby uzywania klas wynikają z mojego rozumienia objektów(nie chodzi mi o objekty w samym sensie informatycznym, tylko po prostu o objekty, o rozumienie tego słowa). Jezeli chodzi o to, że masz mi za złe, że nie używam w bieżącym momencie czasu wszystkich dobrodziejstw klas(dziedziczenie, funkcje wirtualne, polimorfizm itd.), to wynika to z małej zaawansowaności aplikacji. Uzycie ich jest tutaj kwiestią czasu, mam rozplanowane w miarę ich uzycie(oczywiście nie bezcelowe, na pokaz, tylko słuszne i ułatwiające wiele rzeczy). Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 14 Listopada 2009 Udostępnij Opublikowano 14 Listopada 2009 Jakich dobrodziejstw? To nawet nie jest klasa tylko PODS'y, które nic z klasami nie mają wspólnego. Powinieneś chociaż używać metod dostępowych, które pozwolą innym zrozumieć twój kod i znaleźć błąd bez błądzenia po masie niespójnego i nieprzemyślnego kodu. Zaplanowane? Znaczy, że aplikacja tylko po części ma być zgodna z zasadami programowania? Jak będę miał czas przerobie twój kod i wtedy spróbuje znaleźć w nim błąd i pokaże Ci, że przestrzeganie kilku prostych zasad na prawdę ułatwia pisanie. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 14 Listopada 2009 Udostępnij Opublikowano 14 Listopada 2009 inst_block[i]->x_grid=x_rand; inst_block[i]->x=inst_block[i]->x_grid+0.5*inst_block[i]->a; inst_block[i]->y_grid=y_rand; inst_block[i]->y=inst_block[i]->y_grid+0.5*inst_block[i]->a; Twój stary kod: inst_block[i]->x_grid=x_rand; inst_block[i]->x=inst_block->x_grid+0.5*inst_block->a; inst_block[i]->y_grid=y_rand; inst_block[i]->y=inst_block->y_grid+0.5*inst_block->a; Nie dziw się, że nikt tego nie zauważył. Pamiętaj, że twój kod to twoja wizytówka. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
RaistlinBlackRobe Opublikowano 14 Listopada 2009 Autor Udostępnij Opublikowano 14 Listopada 2009 Dzięki wielkie. Zawsze musze walnąć jakiś głupi, prosty błąd, ale taki, że trudno go dostrzec. W takim razie: w jaki sposób podporządkować moje aplikacje całkowicie tym ogólnym zasadom? W tych celach, w jakich tu wykorzystałem klasy trudno byłoby mi użyć czegoś innego do uzyskania takiego samego efektu. Z drugiej strony: czy to oznacza, że zgodność z zasadami zakłada użycie pewnych rzeczy, nawet gdy nie są one tu potrzebne, czy to moja zła interpretacja? Jezeli chodzi o metody dostępowe, to chodzi tu po prostu o metody, które zwracają jakieś pole, tak? Mógłbyś zobrazować w jaki sposób dodają czytelności kodowi? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 14 Listopada 2009 Udostępnij Opublikowano 14 Listopada 2009 Efekt będzie ten sam ale będzie bardziej przejrzyście, bezpieczniej, z możliwością późniejszego rozbudowania itp. Po pierwsze podałem deklaracje mojej klasy(Usunąłem komentarze). Wygląda czytelniej niż twoja. Poza tym (również na przykładzie mojej klasy) według twojego myślenia dodanie listenera wyglądało by tak: object.Windows.push_back(Listener) w moim object.addListener(Listener). Pomijam możliwość obsługi błędów i konieczność znalezienia szukanego okna. Druga sprawa: Załóżmy, że pewna zmienna jest tablicą nawet przykład z twojego kodu: obj_block* inst_block[2]; Gdyby był to element klasy nie zrobiłbyś błędu gdyż element pobrałbyś metodą: obj_block* GetObjBlock(unsigned index) { if(index>=m_uMaxCount)//obsluga bledu return m_aBlocks[index]; } Wtedy twoje obliczenia wyglądały by tak: m_Object.SetXGrid(x_rand); m_Object.setX( m_Object.getXGrid()+0.5*m_Object.getA() ); A my musielibyśmy co najwyżej sprawdzić definicje metod a nie babrać się w masie makaronu. Używanie zmiennych globalnych też nie jest dobrym pomysłem. Najlepiej dane wpakować w odpowiednie klasy z odpowiednimi nazwami metod i składowych(na pewno nie 'a'). Jest jeszcze masa innych rzeczy ale to już musisz kupić książkę i przeczytać odpowiednie rozdziały. 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ę