Raalsky Opublikowano 13 Sierpnia 2012 Udostępnij Opublikowano 13 Sierpnia 2012 Witam Mam strukturę "street", która oznacza ulicę. Ma właściwość jaką jest parent, czyli do jakiego "miasta" przynależy, czyli wskaźnik na strukturę "town". W strukturze "town" mam wektor wskaźników na ulice oraz metodę, która dodaje kolejne wskaźniki do tego wektora. Chciałbym, aby przy każdym dodawaniu ulicy dana ulica miała ustawianego "ojca" na strukturę town dla której została wywołana ta metoda. Brzydkim rozwiązaniem byłoby wrzucanie tego przez argumeny metody, bo podobne metody mam jeszcze przy kilku strukturach. Poszukuję czegoś typu "this" z klas, ale dla struktur. struct town; struct street { town * parent; }; struct town { vector<street *>streets; void push_street( street * p ) { streets.push_back( p ); p->parent = WSKAŹNIK NA AKTUALNĄ STRUKTURĘ } } Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Tymon Opublikowano 13 Sierpnia 2012 Udostępnij Opublikowano 13 Sierpnia 2012 Pracując ze strukturami tak się nie robi, lepiej przepisz to na klasę. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Floodnik Opublikowano 13 Sierpnia 2012 Udostępnij Opublikowano 13 Sierpnia 2012 Jedyną różnicą między klasą a strukturą w c++ jest domyślny specyfikator dostępu, więc różnicy nie ma. Struct ma też wskaźnik this, tak samo jak class, więc w czym problem? #include <vector> struct town; struct street { town* parent; }; struct town { std::vector<street*> streets; void push_street(street* p) { streets.push_back(p); p->parent = this; } }; Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Raalsky Opublikowano 13 Sierpnia 2012 Autor Udostępnij Opublikowano 13 Sierpnia 2012 GCC(g++) jakoś nie trawił używania this wraz ze strukturą. Dzięki, że mi to pokazałeś. Będę dalej kombinował. Bodajże używałem this jako elementu a nie jako wskaźnika na element i dlatego miałem problemy. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Floodnik Opublikowano 13 Sierpnia 2012 Udostępnij Opublikowano 13 Sierpnia 2012 Używam Code::Blocks z kompilatorem GCC i nie ma problemów. Jeszcze przykładowy kod prezentujący, że powyższa metoda działa: //bla bla #include <iostream> using namespace std; //bla bla int main() { town a; cout << &a << endl; a.push_street(new street); cout << a.streets.back()->parent << endl; }; Konsola pokaże dwa takie same adresy. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Raalsky Opublikowano 13 Sierpnia 2012 Autor Udostępnij Opublikowano 13 Sierpnia 2012 Okej, problem leży trochę w innym miejscu. Daję pełny kod: #include <iostream> #include <vector> using namespace std; //Opakowanie strutkur w przestrzeń nazw "world" namespace world { //Preinformowanie kompilatora o użytych strukturach struct stTown; struct stHouse; struct stMan; //Struktura ulicy struct stStreet { //Nazwa ulicy string name; //Wektor wskaźników na domy vector<stHouse *>house; //Miasto do którego przynależy stTown * parent; //Konstruktor stStreet( string tName , stTown * p = NULL ) { name = tName; parent = p; }; }; //Typ do przechowywania informacji o płci danej osoby enum enSex { MALE , FEMALE }; //Struktura miasta struct stTown { //Każde miasto ma swoją nazwę np. "Warszawa" string name; //Wektor wskaźników na ulice vector<stStreet *>street; //Konstruktor stTown ( string tName ) { name = tName; }; //Dodawanie ulicy void push_street( stStreet * p ) { street.push_back( p ); street.back()->parent = this; } //Usuwanie ulicy void pop_street( stStreet * p ) { vector<stStreet *>::iterator it; int i; for( i=0; i<street.size(); i++ ) { if( street[i] == p ) break; } it = street.begin()+i; street.erase(it); } }; //Struktura domu struct stHouse { //Numer domu int number; //Wektor wskaźników na mieszkańców vector<stMan *>in; //Konstruktor stHouse( int tNumber ) { number = tNumber; }; }; //Struktura mieszkańca struct stMan { //Płeć enSex sex; //Wiek int age; //Imię string firstname; //Nazwisko string lastname; //Dom stHouse * home; //Konstruktor stMan( string tFirstname , string tLastname , int tAge , enSex tSex ) { firstname = tFirstname; lastname = tLastname; age = tAge; sex = tSex; }; //Przyłącz do domu void bind( stHouse * p ) { home = p; stMan * c = this; p->in.push_back( c ); }; }; //Globalne wektory zawierające same struktury vector<stTown>gTown; vector<stStreet>gStreet; vector<stHouse>gHouse; vector<stMan>gMan; }; Problem leży po stronie kolejności definiowania struktur itp. Gdy chcę się odwołać do właściwości, która jeszcze nie istnieje, ale mam zdefiniowany "nagłówek" struktury to kompilator wywala błąd. Ehh, dość ciężkie było do znalezienia. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Floodnik Opublikowano 13 Sierpnia 2012 Udostępnij Opublikowano 13 Sierpnia 2012 Kompilacja przebiega pomyślnie. Jedyne, co zrobiłem, to dodanie funkcji main. Jaka jest treść tego błędu? PS. Jeszcze coś, do czego bym się przyczepił: void push_street( stStreet * p ) { street.push_back( p ); street.back()->parent = this; } Po co tak? :P Trochę naokoło. Nie lepiej zrobić p->parent = this; street.push_back(p); ? No i kolejna sprawa, tak jak mówił Tymon - używaj klas. Oczywiście na upartego możesz używać struktur, tylko w odpowiednich miejscach wstaw specyfikatory private/public/protected. Chodzi o bezpieczeństwo - wszystkie elementy klasy, które mogą być prywatne, powinny takie być. Dostęp do nich udzielaj metodami. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Raalsky Opublikowano 13 Sierpnia 2012 Autor Udostępnij Opublikowano 13 Sierpnia 2012 Ja nie mówię, że to źle działa. Problem nie był z samym "this", ale z kolejnością definiowania struktur. Podałem poprawnie działający kod. Problem jest taki: struct a; struct b { a * parent; void bla( a * p ) { p->val = 4; }; }; struct a { int val; b * son; } I tutaj będzie problem. Bo, aby uniknąć problemów to najpierw definiuję tylko "wspomnienie" o strukturze A. Potem W strukturze B używam wskaźnika na A oraz mam metodę, która używa jakiejś właściwości z A, którą dopiero definiuję później. Czy jest możliwość, aby najpierw zdefiniować tak jakby część struktury, a potem dopisać do tego całą resztę? @up: spokojnie, użyłem tego szukając błędu. Poprzedni fragment wyglądał tak jak powinien "p->parent". Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Floodnik Opublikowano 13 Sierpnia 2012 Udostępnij Opublikowano 13 Sierpnia 2012 struct a; struct b { a* parent; void bla( a* p ); }; struct a { int val; b* son; }; void b::bla(a* p) { p->val = 4; }; Jeśli chcesz, żeby "bla" była funkcją inline(a taką jest, kiedy definiujesz ją w środku klasy/struktury), to dopisz z przodu inline. inline void b::bla(a* p) { p->val = 4; }; Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Raalsky Opublikowano 13 Sierpnia 2012 Autor Udostępnij Opublikowano 13 Sierpnia 2012 Miodnie. Tak, wiem co oznacza inline. Znam też klasy. Po prostu zbyt mało o strukturach znalazłem materiałów i nie wiedziałem jak głęboko sięga to utożsamianie się z klasami. Znasz jakiś dobry kurs średnio zaawansowanego C++? Uczyłem się z: http://cplusplus.com/files/tutorial.pdf ,jednak przyda się jeszcze jakieś materiały. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Floodnik Opublikowano 13 Sierpnia 2012 Udostępnij Opublikowano 13 Sierpnia 2012 Nie mam porównania, bo uczyłem się tylko z jednego kursu - http://xion.org.pl/productions/texts/coding/megatutorial/ Od strony technicznej. Potem pozostaje nauka poszczególnych bibliotek(które będą Ci potrzebne) i różnych informatycznych zagadnień, już luźno związanych z samym językiem. Materiałów na internecie jest pełno, gdy zobaczysz w czyimś kodzie słówko, z którym się nie spotkałeś, po prostu wklepujesz je w google. 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ę