Klasy zagnieżdżone - jaki jest sens ich stosowania?

0

Czy może mi ktoś wytłumaczyć jaki jest sens stosowania klas zagnieżdżonych?
Jakie są zalety takiego tworzenia klas? Co mi to daje? Przeczytałem, że czasami może to być wygodniejsze, ale póki co jakoś nie dostrzegam tej wygody...
Z góry dziękuję za wyjaśnienie

0

Wszędzie tam, gdzie dany typ jest na tyle zależny od innego typu, że nie ma sensu definiować go poza tym drugim typem. Dobrym przykładem mogą być tutaj iteratory.

0

W C++ jest to jedynie ukrywanie implementacji, Java daje tutaj trochę więcej możliwości. Ogólnie to, co nie jest bezpośrednio potrzebne na zewnątrz zamykasz w klasie zagnieżdżonej.

0

Ot po prostu ułatwiają organizację kodu. Np. piszesz jakąś strukturę danych (dla przykładu założę, że to hash mapa) i potrzebujesz wewnątrz niej dodatkowej struktury, która będzie trzymać parę klucz-wartość. Użytkownik nie powinien mieć do niej dostępu (bo po co mu to?), zatem możesz umieścić taką strukturkę w prywatnej części klasy i po kłopocie.

Inny przykład to wszelkiego rodzaju kontenery z biblioteki standardowej (np. vector, map). Każdy z nich ma w sobie iterator. I o ile całkowicie możliwe technicznie byłoby umieszczenie obu w przestrzeni std, to znacznie wygodniej jest, gdy iterator jednak siedzi w klasie kontenera. Po pierwsze łatwiej się pisze, bo masz od razu dostęp do innych prywatnych elementów klasy, wiesz dla jakiej klasy piszesz iterator (gdybyś pisał go oddzielnie, to musiałbyś albo robić coś w stylu vector_iterator<T>, map_iterator<T>, albo podawać typ kolekcji jako argument szablonu - oba niezbyt fajne). Poza tym jest też wygodniejsze dla użytkownika, bo w swoim kodzie może zrobić:

typedef map<string, string> Collection;

i potem używać typu Collection, a typ iteratora to po prostu Collection::iterator - i nagle okazuje się, że zmiana std::map na std::unordered_map jest trywialna. W przeciwieństwie do hipotetycznej sytuacji, gdy mamy std::map i std::map_iterator.

0

Dzięki wszystkim za odpowiedzi.
Mam jeszcze jedno pytanie: czy da się w klasie wewnętrznej odwołać do metody lub pola klasy zewnętrznej?

0

Jeżeli masz kod, który musi coś takiego zrobić to jest to źle zaprojektowane. I najlepiej to przeprojektować niż brnąć.

0

Mam jeszcze jedno pytanie: czy da się w klasie wewnętrznej odwołać do metody lub pola klasy zewnętrznej?

Da się.

#include <iostream>
using namespace std;

struct Foo {
	struct Bar {
		int a, b;
	};
	
	Bar bar() {
		return Bar { x, y };	
	}
	
	int x, y;
};

int main() {
	Foo f { 123, 321 };
	Foo::Bar b = f.bar();
	cout << b.a << endl;
	return 0;
}
0

Dzięki @n0name_l ale chyba nie do końca o to mi chodziło.
Zastanawiałęm się, czy jest możliwość zrobić coś w tym stylu:

class A
	{
	public:
		class B
			{
			public:
				int fun()
					{
					return a;
					}
			};

		B b;
		int a;
	};

Niestety powyższy kod się nie kompiluje ;-(.
Próbowałem również dodać operator zakresu tj. return A::a - bez powodzenia.

0

Takie coś nie ma prawa działać, bo obiekty klasy B mogą istnieć niezależnie od obiektów klasy A. Można np. stworzyć:

std::vector<A::B> arr(32);

I co w takim wypadku oznaczałoby return a;

?

Możesz za to dodać dodatkowy argument konstruktora klasy B - referencja do klasy A, a następnie odwoływać się za pomocą jej do pól klasy A. Dodatkowo możesz ten konstruktor uczynić prywatnym, by tylko klasa A mogła tworzyć obiekty typu B (i przy okazji dorzucać do konstruktora referencje do samej siebie).

1 użytkowników online, w tym zalogowanych: 0, gości: 1