• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z odwołaniem się z poziomu jednej klasy do wskaźnika do obiektu w innej klasie

VPS Starter Arubacloud
0 głosów
177 wizyt
pytanie zadane 2 września 2017 w C i C++ przez wojtekd09 Początkujący (260 p.)

Witam,

Mam problem z odwołaniem się z jednej klasy do wskaźnika w innej klasie. Otóż jest taka klasa (w uproszczeniu):


class CSolidHoopsView : public CHoopsView, public HJoyStickListener 
{ 
     public: 
        BODY * bod[3] = {0,0,0}; 
}

a w niej tablica wskaźników bod. Potem wywołuję sobie funkcję tej klasy CSolidHoopsView z poziomu menu (to jest tylko wycinek kodu)

void CSolidHoopsView::OnDodajDodrzewa(){

     MyBody = (BODY*)HA_Compute_Entity_Pointer(key, BODY_TYPE);
	
	 bod[nr_cechy] = MyBody; 
}

I teraz chciałbym się do tego wskaźnika bod odnieść w klasie okna dialogowego CCechy,aby tam pobrać wartości. Tworzę sobie zatem wskaźnik view2 do klasy CSolidHoopsView

class CCechy : public CDialog, public WindowsTreeGraph
{
     CSolidHoopsView * view2;
}

W konstruktorze inicjalizuję wskaźnik zerem, a w destruktorze niszczę.

W funkcji tej klasy CCechy chcę odnieść się do składowych tego obiektu poprzez wskaźniki

ff = view2->bod[data]->lump()->shell()->face();

I tu się pojawia problem, ponieważ na tej powyższej linijce program się zawiesza i mam błąd typu Access violation, a przy debugowaniu, gdy sprawdzam zawartość bod, to wszystkie wskaźniki mają wartość 0, a także mam

Unable to read memory tak jakby wskaźnik się gubił.

Gdy tę linijkę

ff = view2->bod[data]->lump()->shell()->face();

zamieszczę w funkcji tej samej klasy tzn. CSolidHoopsView, to wszystko działa jak należy.

Może mi ktoś podpowiedzieć co robię źle? Bo myślę, że ten sposób da się wykorzystać, bo np. przy próbie odwołania się poprzez wskaźnik view2 do zmiennej int błędu nie ma - wartość się pobiera. Problem jest ze wskaźnikami. Dodam, że obie klasy są w różnych plikach.

Zamieściłem tylko fragment kodu, bo zawiera on funkcje kernela graficznego.

1 odpowiedź

0 głosów
odpowiedź 2 września 2017 przez j23 Mędrzec (194,920 p.)

W konstruktorze inicjalizuję wskaźnik zerem, a w destruktorze niszczę.

A inicjalizujesz go czymś jeszcze poza nullem? Jeśli nie, to już masz odpowiedź, dlaczego dostajesz błąd AV.

komentarz 2 września 2017 przez wojtekd09 Początkujący (260 p.)
Nie wiem czym innym miałbym go zainicjalizować. Tym bardziej, że do zmiennych typu int mam dostęp przez ten wskaźnik, tylko do innego wskaźnika już nie bardzo. Tzn. dostęp jest, ale jakby na nic konkretnego nie pokazywał.
komentarz 2 września 2017 przez j23 Mędrzec (194,920 p.)

Z Twojego opisu wynika, że view2 ma wartość NULL (ustawioną w konstruktorze). Nigdzie nie piszesz, że gdzieś temu wskaźnikowi przypisujesz poprawny adres. I stąd moje pytanie.

 

W jaki sposób przypisujesz adres temu wskaźnikowi?

 

Twierdzisz, że tablica bod ma same zera. A sprawdzałeś, czy przed feralnym wywołaniem tablica ta jest poprawnie wypełniona?

 

 

komentarz 2 września 2017 przez wojtekd09 Początkujący (260 p.)

Tablica się wypełnia - element zerowy ma jakąś wartość, bo tylko tą ustawiam na razie.

Natomiast teraz już nie wiem na co powinienem ustawić wskaźnik view2. On ma pokazywać na klasę CSolidHopsView. Więc jeśli poprzez operator -> się odwołam do jakiegoś konkretnego obiektu tej klasy np. view2->bod[0], to nie powinno działać?

komentarz 2 września 2017 przez j23 Mędrzec (194,920 p.)

view2 powinien wskazywać na istniejący obiekt klasy CSolidHopsView. Twierdzisz, że w trakcie błędu tablica bod jest wyzerowana, choć nie powinna. Dlatego ważne jest pytanie, jaki obiekt przypisujesz wskaźnikowi view2. Takie akcje często dzieją się wtedy, gdy odwołujesz się do obiektu, który został zniszczony, ponieważ był np. tymczasowy (czasami po usunięciu obiektu dostęp do jego pól jest możliwy, chociaż zawartość może być zmieniona).

 

A może odwołujesz się do innego obiektu niż ten, który wypełniasz poprawnymi danymi. Sprawdź adresy.

komentarz 2 września 2017 przez wojtekd09 Początkujący (260 p.)

No właśnie źle się odwoływałem do tego obiektu, bo CSolidHoopsView to klasa MFC określająca Widok. Te linijki pomogły

CMDIFrameWnd *pFrame =
		(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;

	CMDIChildWnd *pChild =
		(CMDIChildWnd *)pFrame->GetActiveFrame();

	
	CSolidHoopsView *pView = (CSolidHoopsView *)pChild->GetActiveView();

I dopiero na tym pView można się odwołać do tablicy bod.

Podobne pytania

+1 głos
1 odpowiedź 247 wizyt
0 głosów
0 odpowiedzi 114 wizyt
0 głosów
1 odpowiedź 105 wizyt

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...