Projekt klas

0

Chcę zaprojektować klasę węża w grze.

Mam coś takiego:

  1. Klasa podstawowa: wąż
  • elementy: położenie, kolor
  • funkcje: idźDoGóry(), idźNaDół(), idźWLewo(), idźWPrawo()

2.1) Klasa potomna1: wąż strzelający

  • elementy: ilość nabojów
  • funkcje: strzelaj()

2.2) Klasa potomna2: wąż szybszy

  • elementy: ilość przyspieszeń "TURBO" do wykorzystania
  • funkcje: użyj_turbo()

W grze chcę użyć wskaźnika na obiekt klasy podstawowej, a później w zależności od rundy (w której wąż będzie mógł strzelać, albo być szybszy, albo po prostu będzie mógł tylko się poruszać), przypisywać do niego adresy obiektów klasy podstawowej, pochodnej1 lub pochodnej2.

Aby użyć funkcji strzelaj() lub użyj_turbo() z klas potomnych, muszę je zadeklarować jako wirtualne w klasie podstawowej.

PYTANIE: Czy to jest prawidłowe (w sensie dobrego stylu programowania)? Bo kompilator przecież skompiluje jeżeli dla obiektu klasy podstawowej użyję tych metod, lub jeżeli np. dla obiektu klasy potomnej1 będę chciał użyć metody użyj_turbo(). Co prawda nic wtedy nie wykona, ale skompiluje.

Jak to wszystko połączyć? Czy to w ogóle dobry pomysł z metodami wirtualnymi?

Miałem też pomysł żeby użyć osobnych wskaźników dla każdej klasy. Wtedy obyłoby się bez metod wirtualnych. Tylko że wtedy za każdym razem trzebaby przekazywać sterowanie, a tak to mam jeden wskaźnik do klasy podstawowej i za każdym razem go używam, bez względu na to czy jest tam obiekt klasy potomnej czy podstawowej.

0

Chcę zaprojektować klasę węża w grze.

Mam coś takiego:

  1. Klasa podstawowa: wąż
  • elementy: położenie, kolor
  • funkcje: idźDoGóry(), idźNaDół(), idźWLewo(), idźWPrawo()

2.1) Klasa potomna1: wąż strzelający

  • elementy: ilość nabojów
  • funkcje: strzelaj()

2.2) Klasa potomna2: wąż szybszy

  • elementy: ilość przyspieszeń "TURBO" do wykorzystania
  • funkcje: użyj_turbo()
HTMLame napisał(a)

W grze chcę użyć wskaźnika na obiekt klasy podstawowej, a później w zależności od rundy (w której wąż będzie mógł strzelać, albo być szybszy, albo po prostu będzie mógł tylko się poruszać), przypisywać do niego adresy obiektów klasy podstawowej, pochodnej1 lub pochodnej2.
Aby użyć funkcji strzelaj() lub użyj_turbo() z klas potomnych, muszę je zadeklarować jako wirtualne w klasie podstawowej.

:/ uuu... pchanie metody wirtualnych na siłę...

HTMLame napisał(a)

PYTANIE: Czy to jest prawidłowe (w sensie dobrego stylu programowania)? Bo kompilator przecież skompiluje jeżeli dla obiektu klasy podstawowej użyję tych metod, lub jeżeli np. dla obiektu klasy potomnej1 będę chciał użyć metody użyj_turbo(). Co prawda nic wtedy nie wykona, ale skompiluje.

Ekm jeśli nie zrobisz implementacji metody wirtualnej w kolejnej klasie /czytaj: jeśli metoda wirtualna nie będzie miała implementacji w wyższej klasie/ nie skompiluje to w ogóle...
Implementacja pustych funkcji dla klas wcześniejszych? Hmm, niby by przeszło, ale zapominasz o jendej rzeczy, pomiędzy levelami (zmianą tych funkcjonalności węża) będziesz musiał usunąć poprzedni obiekt i na nowo utworzyć obiekt wyższy, żeby metody wyższe zaczęły działać, trochę bez sensu...

HTMLame napisał(a)

Jak to wszystko połączyć? Czy to w ogóle dobry pomysł z metodami wirtualnymi?

no nie za bardzo...

HTMLame napisał(a)

Miałem też pomysł żeby użyć osobnych wskaźników dla każdej klasy. Wtedy obyłoby się bez metod wirtualnych. Tylko że wtedy za każdym razem trzebaby przekazywać sterowanie, a tak to mam jeden wskaźnik do klasy podstawowej i za każdym razem go używam, bez względu na to czy jest tam obiekt klasy potomnej czy podstawowej.

IMO to już ma większy sens niż poprzednie, ale też nie jest to do końca trafione, bo po prostu jak mówisz po co używać trzech obiektów, jak możesz jednego :>

Mnie to się widzi coś takiego:
W ogóle nie potrzebnie pchasz tu metody wirtualne, bo niepotrzebnie pchasz tu dziedziczenie (chociaż niekoniecznie, zaraz o tym powiem)...
Zrób jedną klasę i się nie piernicz, zrobisz jeden obiekt ze wszystkim i masz spokój, po prostu na pierwszych levlach nie będziesz używał tych metod z bonusami, albo jeśli nie chcesz tego kontrolować z poziomu wywołania, kontroluj z poziomu tej metody, czyli wywołuj turbo nawet na pierwszym levlu (nie przejmuj się w ogóle levlem) i przekazuj jakiś parametr levla, etc. do turbo, tak aby to ta funkcja mogła ocenić czy to już można użyć dopalacza czy nie...
Ewentualnie zachowaj dziedziczenie, ale od początku twórz i używaj obiektu najwyższego, a klasy podrzędne niech istnieją tylko do logicznego rozdzielenia funkcjonalności węża, żeby kod ładniej wyglądał jak chcesz...

A metody wirtualne kolego służą do innych zastosować. Podstawowym zastosowaniem jest sytuacja, gdy istnieje kilka innych klas na tym samym poziomie, np. gdybyś miał kilka rodzai tych węży, ale każdy by miał taką samą funkcjonalność (zbiór metod), ale każdy w inny sposób je wykonywał, wtedy robisz 1 podstawowy interfejs (klasa z samymi metodami wirtualnymi), która ma tylko owe metody wirtualne, a następnie te kilka klas węży, które implementują ten interfejs, czyli określają jak te metody wirtualne mają działać w danej klasie (wężu)...
Dzięki temu możesz stworzyć jeden z obiektów węża i używać go tak samo jak innych, np. możesz stworzyć tablicę takich obiektów:

ISnake* tab[2];
tab[0] = new SnakeOgrodowy;
tab[1] = new SnakeBoa;
for(int i = 0; it < 2; i++) tab[i]->Idz(lewo);

i + jest w tym, że w zależności od typu obiektu wywołają się różne implementacje Idz

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