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

C++ Czy obiekt (B) będący polem innego obiektu (A) może modyfikować jego zmienne?

42 Warsaw Coding Academy
0 głosów
680 wizyt
pytanie zadane 29 stycznia 2018 w C i C++ przez DarkEliat Bywalec (2,810 p.)
edycja 29 stycznia 2018 przez criss

Witam.

Pisząc moją grę w SFML (ta informacja chyba nie ma tutaj znaczenia) często mam problem taki jak w pytaniu.

Pierwszy banalny przykład, który przychodzi mi do głowy:

class A
{
public:
	A()
	{
		value1 = 1;
		value2 = 2;
	}

	B b;

	int value1;

	void function()
	{
        // Jakiś kod ...

		b.doSomething(); // Takie coś musi występować, bo kod, który piszę zajmuje się także swoimi zmiennymi prywatnymi

        // Jakiś kod ...
	}

private:
	int value2;
};

class B
{
public: 
	B()
	{}

	void doSomething()
	{
		// Czasem potrzebuję zmienić albo tylko skorzystać ze zmiennej publicznej rodzica np.
		value = value1; // Wiem, że to jest zły zapis, ale czegoś takiego oczekuję

		// W pojedynczych przypadkach potrzebuję skorzystać ze zmiennej prywatnej
		// Wiem, że tutaj trzeba "zaprzyjaźnić" klasy, ale dalej jest ten sam problem,
		// Jak odwołać się do zmiennej rodzica?
		value = value2;
	}

	int value;

};

Później oczywiście w main z tego skorzystam:

int main()
{
	A a;
	a.function();
}

To co tutaj przedstawiłem wydaje się zbędne, bo zawsze można to jakoś obejść (ale z podobnymi sytuacjami spotykam się coraz częściej). Z tym że ja nie szukam sposobu obejścia, ponieważ musiałbym zmieniać połowę kodu w mojej grze i tworzyć mnóstwo (moim zdaniem) zbędnych funkcji.

Czy jest  jakikolwiek sposób dostępu do wartości klasy rodzica (A) POMIJAJĄC podawanie odpowiednich pól lub całej klasy (A) jako argumenty metody klasy B (za dużo z tym roboty i powielania tego samego kodu)? 

 

P.S. Jeśli coś nie jest jasne, proszę pytać.

komentarz 29 stycznia 2018 przez j23 Mędrzec (195,240 p.)

No dobrze, ale dlaczego klasę A nazywasz rodzicem (w domyśle klasy B)? Klasa A byłaby rodzicem, gdyby B dziedziczyła po niej, a tak...

komentarz 29 stycznia 2018 przez DarkEliat Bywalec (2,810 p.)
W sumie możliwe, że popełniłem błąd w nazewnictwie. Nie mniej jednak rozumiesz co mam na myśli?
komentarz 29 stycznia 2018 przez j23 Mędrzec (195,240 p.)
Tak, dałem odpowiedź niżej.
komentarz 29 stycznia 2018 przez DarkEliat Bywalec (2,810 p.)
A, nie spojrzałem na nick ;)
komentarz 29 stycznia 2018 przez criss Mędrzec (172,590 p.)
Edytowałem nazwe tematu ze względu na ten wspomniany błąd
komentarz 29 stycznia 2018 przez DarkEliat Bywalec (2,810 p.)
Dzięki ;)

2 odpowiedzi

0 głosów
odpowiedź 29 stycznia 2018 przez j23 Mędrzec (195,240 p.)

Nic tu nie wykombinujesz... Klasa B musi mieć wskaźnik/referencję do obiektu klasy A, jeśli chce mieć dostęp do jego pól.

komentarz 29 stycznia 2018 przez DarkEliat Bywalec (2,810 p.)
Coś wykombinowałem. Moja pokręcona odpowiedź znajduje się w mojej odpowiedzi pod pytaniem. Pozdrawiam.
–1 głos
odpowiedź 29 stycznia 2018 przez DarkEliat Bywalec (2,810 p.)
edycja 29 stycznia 2018 przez DarkEliat

Problem udało mi się rozwiązać, faktem, że w sposób trochę dziwny i możliwe, że to jest właśnie takie "obejście", o którym wspominałem w pytaniu, ale działa :D

Postaram się tu przepisać uproszczoną wersję tego kodu, bo moja jest mocno związana z działaniem gry, dlatego mogłaby być nieczytelna:

// ObjectsReferences.h (Nowy Plik)
#include "A.h"

using namespace std;

extern A *aReference;

int *getValue1Reference();
int *getValue2Reference();
// ObjectsReferences.cpp (Nowy Plik)
#include "ObjectsReferences.h"

A *aReference;

int *getValue1Reference()
{
	return &aReference->value1;
}

int *getValue2Reference() // Ta funckja będzie musiała zostać zaprzyjaźniona z klasą A, bo próbuje  uzyskać dostęp do prywatnych danych
{
	return &aReference->value2;
}
// A.h
class A
{
        // Każda funkcja chcąca korzystać z prywatnych składowych będzie musiała mieć tutaj swoją własną linijkę
	friend int *getValue2Reference(); 

public:
	A();

	void function();

	int value1;

private:
	int value2;
};
// A.cpp
#include "A.h"

A::A()
{}

void A::function()
{
	b.doSomething();
}
// Klasa B
#include "ObjectsReferences.h"

class B
{
public: 
    B()
    {}
 
    void doSomething()
    {
              value = getValue1Reference();
              value = getValue2Reference();

              // W tym momencie możemy dowolnie manipulować zmiennymi klasy A
              // To samo można zastosować przy obiektach innych klas, tutaj podałem przykład z int
    }
 
    int *value; // To MUSI BYĆ WSKAŹNIK
 
};
//main.cpp
int main()
{
	A a;
	
	extern A *globalObj; // To jest ważna część
	globalObj = &a; // I to

	a.function();
}

Ogólnie rzecz biorąc, kod ma swoje wady, ale jeśli chcemy korzystać tylko z publicznych pól lub funkcji naszej klasy (A), to wystarczy skorzystać z wskaźnika, który u mnie nazywał się 'aReference'.

Mam nadzieję, że komuś pomogłem ;D

komentarz 29 stycznia 2018 przez mokrowski Mędrzec (158,440 p.)
Sobie z pewnością. Nie widzisz nic ... "dziwnego" w zadawaniu pytań na które sam sobie odpowiadasz a co ważniejsze sam akceptujesz odpowiedź jako najlepszą? :->
komentarz 29 stycznia 2018 przez DarkEliat Bywalec (2,810 p.)
Może to dziwne, ale odpowiedź napisałem dla innych użytkowników i po to ją oznaczyłem. Bo to działa.
komentarz 29 stycznia 2018 przez DarkEliat Bywalec (2,810 p.)
A nie chciałem zamykać pytania, może ktoś wymyśli coś mądrzejszego ;)
komentarz 29 stycznia 2018 przez j23 Mędrzec (195,240 p.)

Już chyba lepiej byłoby, gdybyś zrobił to w ten sposób (przy założeniu, że A ma być singletonem), zamiast bawić się w globalny wskaźnik:

class A
{
	...
	A() {}

public:
	...

	static A& get() 
	{   
		static A a;
		return a;
	}
};


class B
{
	...

	void doSomething()
	{
		value = A::get().value1;

		...

		value = A::get().value2;
	}
};

 

Podobne pytania

0 głosów
1 odpowiedź 426 wizyt
0 głosów
4 odpowiedzi 296 wizyt
0 głosów
1 odpowiedź 1,942 wizyt
pytanie zadane 31 października 2017 w Sprzęt komputerowy przez niezalogowany

93,382 zapytań

142,382 odpowiedzi

322,539 komentarzy

62,740 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

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...