Autor Wątek: Dziedziczenie i wywołanie bazowe implicite  (Przeczytany 1436 razy)

Offline kubera

  • Użytkownik
    • Prywatna strona

# Marzec 14, 2012, 08:37:38
Witam!

Pytanko, jak Wy rozwiązujecie problem, pliz.
Posiadam drzewo klas.
Każda instancja klasy implementuje metodę OnD3D11ShaderBlaBla.
Chcę, ażeby wykonały się wszystkie metody (każdej klasy/nadklasy),
po których przejdzie iterator/rekursja.

struct A
{
  virtual void OnD3D11ShaderBlaBla() {...}
};

struct B : public A
{
  virtual void OnD3D11ShaderBlaBla() {...}
};

Rzecz w tym, ażeby załować obie te metody, lecz bez explicitie bez kodowania w stylu:

void OnD3D11ShaderBlaBla()
{
 A::OnD3D11ShaderBlaBla();
 ...
}

Jak nazywa się wzorzec, który możecie zasugerować?

Jeśli boost coś takiego implementuje, to bardzo dobrze.

Dzięki.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline karol57

  • Użytkownik

  • +1
# Marzec 14, 2012, 08:50:04
Chodzi ci o coś w stylu:
LPA obj1 = new A(10,4,2);
/* kilka takich objektow. */
pEventMenager->OnShaderCosTam();
// I żeby to wywołało na wszystkich obiektach A ta metodę?
To poczytaj o Boost.Signals.

//EDIT: A nie źle cię zrozumiałem...
« Ostatnia zmiana: Marzec 14, 2012, 08:54:46 wysłana przez karol57 »

Offline kubera

  • Użytkownik
    • Prywatna strona

# Marzec 14, 2012, 08:58:00
Tak, ale również motody klas bazowych.
Dzięki za boosta, poczytam.

Offline Liosan

  • Redaktor

# Marzec 14, 2012, 12:08:50
Nie wiem czy istnieje skladnia, zeby z zewnatrz zawolac konkretna funkcje z nadklasy, mimo ze podklasa tez ja implementuje... ale gdyby byla, to...

To tak czysto teoretycznie, to uzywajac SFINAE mozna sie dowiedziec czy klasa ma nadklase, i potem testowac czy ta nadklasa ma taka metode, i jesli ma to ja wywolywac. Czyli mozna by napisac jakies template'owe urzadzonko, ktore z zewnatrz klasy zawola wszystkie metody o takiej samej sygnaturze od korzenia hierarchi klas obiektu ktory jest parametrem az do faktycznego "najdolniejszego" override'u.

Nie wiem co to zrobic przy wielodziedziczeniu, metodach abstrakcyjnych, dziedziczeniu wirtualnym itp. W ogole balbym sie dotykac kodu w ktorym bym to zobaczyl :)

Liosan

Offline deadeye

  • Użytkownik

# Marzec 14, 2012, 13:16:39
Jeśli masz tylko jeden poziom dziedziczenia, to jest prymitywny sposób:

class B : public A
{
  void DoOnShader()
  {
  A::OnD3D11ShaderBlaBla();
  OnD3D11ShaderBlaBla();
  }

}
Dzięki temu w implementacji dziedziczącej metody możesz wywoływać czysty kod, a iterując po obiektach wywołujesz DoOnShader i masz pewność, że wywołają się obie metody Oczywiście taka metoda ma sens tylko jeśli masz pewność że na pewno nadpiszesz tą metode w klasie dziedziczącej.

Offline kubera

  • Użytkownik
    • Prywatna strona

# Marzec 14, 2012, 16:58:39
Dzięki, struktura jest drzewiasta i mało przewidywalna.
Zwyczajnie dodając nową klasę muszę sprawdzać zawsze po czym dziedziczy.
Chciałbym, ażeby klasa bazowa się rejestrowała sama.

U mnie to jest tak, mam dowolny obudowany shader z teksturą,
i zdecydowana większość klas dziedziczy po nim, umiejąc renderować z teksturą.
Rzecz w tym, że one często coś zmieniają, np. dodają drugą.
I tu z żalem stosuję klasykę.
Można ktoś wypracował jakąś fajną metodykę na problem...

Pozdrawiam

Offline Veldrin

  • Użytkownik

# Marzec 14, 2012, 18:01:51
Przedstaw szczegółowo jaki jest problem do rozwiązania, to może znajdą się inne metody.

Bo sytuacja, w której np. nowy materiał różniący się jakimś dodatkowym parametrem oznacza nową klasę, która na dodatek jest częścią złożonej hierarchii to brzmi przerażająco.

Offline Dab

  • Redaktor
    • blog

  • +1
# Marzec 14, 2012, 18:11:16
Dzięki, struktura jest drzewiasta i mało przewidywalna.
Zwyczajnie dodając nową klasę muszę sprawdzać zawsze po czym dziedziczy.
Chciałbym, ażeby klasa bazowa się rejestrowała sama.

#define DECL_CLASS(x, y) class x : public y { typedef y parent;
a potem np.

DECL_CLASS(CoolShader, BoringShader)
public: void RunShader()
{
  parent::RunShader();
  DoFancyStuff();
}


Offline Hans

  • Użytkownik

  • +1
# Marzec 14, 2012, 18:41:29
Jeżeli używasz tylko MSVC to możesz zastosować __super zamiast nazwy klasy bazowej (np. __super::foo(); )

Offline stefan123

  • Użytkownik

# Marzec 14, 2012, 19:52:49
Czy dobrze zrozumialem, ze chodzi o odpowiednik super() ?

Offline Xirdus

  • Redaktor

# Marzec 14, 2012, 20:03:08
Tak.

Offline stefan123

  • Użytkownik

# Marzec 14, 2012, 20:44:03
To mysle, ze mozna zrobic to na preprocesorze. Klase definiuj hashdefinem np #define (klasa,klasabazowa,tresc klasy) i potem klasabazowa::dupa()
« Ostatnia zmiana: Marzec 14, 2012, 20:46:41 wysłana przez stefan123 »

Offline lgromanowski

  • Użytkownik
    • OpenMW, Elderscrolls III: Morrowind engine reimplementation


Offline kubera

  • Użytkownik
    • Prywatna strona

# Marzec 15, 2012, 12:34:28
Dziękuję za bardzo ciekawe odpowiedzi.
Myślę, że wniosły wystarczająco.