DevPort Napisano Marzec 14, 2016 Zgłoś Share Napisano Marzec 14, 2016 Dobra miałem pewien problem ze strony kompilatora C++ struktura klas: class A { public: A(){ b = new B; c = new C;} B* b; C* c; }; Teraz magiczne zdanie: Chciałem dostać się z klasy B do klasy C. Główkowałem cały dzień jak to zrobić, kombinowałem z interfejsami (w delphi/fpc to nie problem) ale poległem. Przyszedł mi jednak pewien pomysł na rozwiązanie problemu. Przekazanie instancji klasy A do pozostałych klas czyli B i C przez konstruktor. Czyli tu mamy błędny kod: B::B(A* base) { } C::C(A* base) { } Ponieważ musimy do plików nagłówkowych klas B i C dołączyć plik nagłówkowy klasy A który zawiera w sobie dołączone pliki nagłówkowe klas B i C. Więc jak? W ukochanym Object Pascalu mamy wskaźnik niejawny : Pointer; 4 bajtowy. W C++ odpowiednikiem jest "void* zmienna;" Ta, wielu więc napisze: to proste więc zamieńmy w konstruktorach A* na void* i po sprawie... Ne ne ne Kompilatorek wywali błąd konwersji I tu szczena mi opadła Ale coś musi być, aby to działało i jest: static_cast więc tak piszę w/g plików: "a.h" #include "B.h" #include "C.h" class A { public: A(); B* b; C* c; } "a.cpp" #include "A.h" A::A() { b = new B(this); c = new C(this); } Teraz pliki pozostałych klas: "b.h" class B { public: B( void* base); } "b.cpp" #include "B.h" #include "A.h" A* mA; B::B(void* base) { mA = static_cast<A*>(base); } "c.h" class C { public: C( void* base); void test(); } "c.cpp" #include "C.h" #include "A.h" #include <iostream> A* mA; C::C(void* base) { mA = static_cast<A*>(base); } void C::test() { std::cout << "Witaj świecie \n"; } Teraz w metodach klasy B możemy używać zapisu: mA->c->test(); Komuś może się przydać taka konstrukcja kodu. Prawdziwy programista wiesza sie wraz ze swoim programem. Link do komentarza Udostępnij na innych stronach More sharing options...
Kaczus Napisano Marzec 15, 2016 Zgłoś Share Napisano Marzec 15, 2016 Ojojoj... W C++ void * należy używac w ostateczności (czyli uzycie takiego to z prawdopodobieństwem 1 użycie błędne). Dodatkowo zmienne globalne... brrr.... Podpowiedć, np plik c.h może wyglądac tak: class A; class C { public: C( A* base); void test(); } Link do komentarza Udostępnij na innych stronach More sharing options...
DevPort Napisano Marzec 15, 2016 Autor Zgłoś Share Napisano Marzec 15, 2016 Testowałeś to ? Możesz podać działający przykład? Albo nie umiem i nie działa, albo gdzieś popełniłeś błąd. Cel to dostęp do klasy, która nas (klasę) stworzyła. Czyli w plikach nagłówkowych klas: B i C nie mogę dołączać pliku nagłówkowego klasy A, ponieważ jej plik nagłówkowy dołącza pliki nagłówkowe klas B i C. Czyli w tych plikach nie dam rady stworzyć zmiennej wskaźnikowej na klasę A. A chcę wykorzystać właśnie funkcje tej klasy. Więc potrzebna mi jej instancja klasy A wewnątrz klas B i C. Odnośnie tego co mi napisałeś kodu to kompilator wypluwa mi błąd przy tworzeniu obiektu C: c = new C(this); odnośnie "Braku dopasowania funkcji dla wywołania C::C(A* const); " rozumiem, że konwersję można spróbować zrobić ale też mi to nie chce działać. Natomiast co do samego wskaźnika, to można w sekcji prywatnej klasy C stworzyć wskaźnik np. "void* baseClass;" i w konstruktorze przypisać: this->baseClass = base; po czym każdorazowe użycie dostępu do nadklasy wiąże się z takową wiązanką kodu: A* aClass = static_cast<A>(this->baseClass); // aClass->b->test(); co można w prywatną funkcję obudować. Prawdziwy programista wiesza sie wraz ze swoim programem. Link do komentarza Udostępnij na innych stronach More sharing options...
Kaczus Napisano Marzec 16, 2016 Zgłoś Share Napisano Marzec 16, 2016 Tak korzystam z tego czasami i to działa. Podaj kod, oraz to co Ci zwraca kompilator - dokładnie, bo coś masz widocznie nie tak. Link do komentarza Udostępnij na innych stronach More sharing options...
DevPort Napisano Marzec 16, 2016 Autor Zgłoś Share Napisano Marzec 16, 2016 OK, dam przykład który wywala w konstruktorze klasy w pliku AClass.cpp z komunikatem: no matching function for call to 'BClass::BClass(AClass* const)'| this->bClass = new BClass(this); A to całość: main.cpp #include "AClass.h" int main() { AClass* aClass = new AClass; delete aClass; } AClass.h #ifndef ACLASS_H #define ACLASS_H #include "BClass.h" #include "CClass.h" class AClass { public: AClass(); virtual ~AClass(); BClass* getBClass(); CClass* getCClass(); protected: private: BClass* bClass; CClass* cClass; }; #endif // ACLASS_H AClass.cpp #include "AClass.h" AClass::AClass() { this->bClass = new BClass(this); this->cClass = new CClass(this); } AClass::~AClass() { //dtor } BClass* AClass::getBClass(); { return this->bClass; } Class* AClass::getCClass(); { return this->cClass; } BClass.h #ifndef BCLASS_H #define BCLASS_H class pAClass; class BClass { public: BClass(pAClass* _AClass_); virtual ~BClass(); void testFunction(); protected: private: pAClass* _aClass; }; #endif // BCLASS_H BClass.cpp #include "AClass.h" BClass::BClass(pAClass* _AClass_) :_aClass(_AClass_) { // this->_aClass = _AClass_; /\ UP /\ } BClass::~BClass() { //dtor } void BClass::testFunction() { std::cout << "test Function message"; } CClass.h #ifndef CCLASS_H #define CCLASS_H class pAClass; class CClass { public: CClass(pAClass* _AClass_); virtual ~CClass(); protected: private: pAClass* _aClass; }; #endif // CCLASS_H CClass.cpp #include "AClass.h" CClass::CClass(pAClass* _AClass_) :_aClass(_AClass_) { // this->_aClass = _AClass_; /\ UP /\ AClass* myClass = static_cast<AClass>(this->_aClass); myClass->getBClass()->testFunction(); } CClass::~CClass() { //dtor } To oczywiście przykład kodu zmodyfikowany na potrzeby metody "po Twojemu" Moja wiedza na temat C++ nie jest wielka więc miło będzie się czegoś dowiedzieć Pozdrawiam. Prawdziwy programista wiesza sie wraz ze swoim programem. Link do komentarza Udostępnij na innych stronach More sharing options...
Kaczus Napisano Marzec 17, 2016 Zgłoś Share Napisano Marzec 17, 2016 A co to za twór class pAClass; Dodatkowo trochę zbyt chojnie wstawiasz średniki Link do komentarza Udostępnij na innych stronach More sharing options...
DevPort Napisano Marzec 17, 2016 Autor Zgłoś Share Napisano Marzec 17, 2016 Z poprzednich Twoich wypowiedzi napisałeś: class A; class C { ... więc to jest zamiast "class A;" Sam to zaproponowałeś. Ps. średniki są na zakończenie instrukcji, co w tym złego? I proszę napisz gdzie widzisz nadmiar średników ? Prawdziwy programista wiesza sie wraz ze swoim programem. Link do komentarza Udostępnij na innych stronach More sharing options...
Kaczus Napisano Marzec 17, 2016 Zgłoś Share Napisano Marzec 17, 2016 Tak napisałem i tak ma być, to było class A, do twojego class A - ma dokładnie tak samo się nazywać! Czyli w przypadku opisanym w drugim przykładzie, co dałes ma być class AClass; Link do komentarza Udostępnij na innych stronach More sharing options...
DevPort Napisano Marzec 17, 2016 Autor Zgłoś Share Napisano Marzec 17, 2016 A to wybacz proszę :] Tak działa wszystko tak jak powinno, wystarczyło wspomnieć, że to ma być prototyp. A o prototypach w C++ zapomniałem. A średniki nie zauważyłem przy pisaniu, w pliku AClass.cpp jest nadmiar przy metodach getBClass() i getCClass(). Kod na szybko pisany. Dzięki za pomoc. Pozdrawiam. Prawdziwy programista wiesza sie wraz ze swoim programem. Link do komentarza Udostępnij na innych stronach More sharing options...
Polecane posty
Zarchiwizowany
Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.