Autor Wątek: Przekazywanie wskaznika do nieistniejacego obiektu  (Przeczytany 1661 razy)

Offline Santor

  • Użytkownik

# Lipiec 20, 2012, 14:20:12
Wyczytalem gdzie tu na forum jak fajnie zorganizować sobie klasy w grze RTS. Stworzylem sobie "głowna" klase , która ma być singletonem i trzymac w sobie całą reszte obiektów. Klasy pozostałych obiektów więc deklaruje ponad delklaracją tej głownej klasy. Do każdego obiektu chce przekazać w konstruktorze wskaźnik do obiektu głownego. I tu pojawie sie problem bo deklaracja klasy głownej znajduje sie nizej w kodzie od reszty i nie moge zadeklarować typu wskaźnika bo wyskakuje błąd. Pytanie, jak to można rozwiązać?

Offline Mr. Spam

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

Offline Avaj

  • Użytkownik

# Lipiec 20, 2012, 14:23:59
class Foo;

class Bar
{
  Foo* f;
};

class Foo
{
  int a;
};

Offline Oti

  • Użytkownik

# Lipiec 20, 2012, 14:26:51
Skoro obiekt główny jest jeden i ten sam, to po co w każdym obiekcie trzymać do niego wskaźnik, zamiast się normalnie, bezpośrednio do niego odwołać?

Offline Santor

  • Użytkownik

# Lipiec 20, 2012, 14:35:12
@ Avaj czyli klasy można deklarować w jednym miejscu a potem dopiero przypisywac im pole? czy cos źle zrozumiałem.

@Oti Po to żeby móc z jednej podklasy odwoływać się do innych podklas zawartych w klasie glownej.

Avaj zrobilem jak radziłeś, kompilator nie czepiał sie juz typu wskaźnika. Tylko teraz wywołuje jakies fukcje przez wskaźnik to kompilator ich nie widzi . Taki błąd wyskakuje:
invalid use of incomplete type 'struct glownaklasa'
 forward declaration of 'struct glownaklasa'|

metode wywołuje tak:
(*main).logi.wpis(jakis argument);
« Ostatnia zmiana: Lipiec 20, 2012, 16:08:59 wysłana przez Santor »

Offline Veldrin

  • Użytkownik

# Lipiec 20, 2012, 20:27:03
Ponawiam dobre pytanie Otiego. Chyba, że coś źle rozumiem architekture.

Jest klasa główna będąca singletonem. Duży innych klas, których obiekty są trzymane w głównej. Chcesz żeby był dostęp, więc starasz się każdemu dać wskaźnik do głównej.

Po co skoro główna jest singletonem?

Offline lgromanowski

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

# Lipiec 20, 2012, 20:33:42
Uzupełnienie tego co podał Avaj:

// nagłówek Bar.h

// bez include "foo.h", tylko forward deklaracja
class Foo;

class Bar
{
  Foo* f; // Wskaźniki i referencje mogą być niekompletnym typem
  void baz();
};

// nagłówek foo.h
class Foo
{
  int a;
  void foo() {}
};

// plik Bar.cpp

// tutaj wciągnij "foo.h"
#include "foo.h"

void Bar::baz()
{
  f->foo();
}

Offline Santor

  • Użytkownik

# Lipiec 20, 2012, 20:54:15
Ponawiam dobre pytanie Otiego. Chyba, że coś źle rozumiem architekture.

Jest klasa główna będąca singletonem. Duży innych klas, których obiekty są trzymane w głównej. Chcesz żeby był dostęp, więc starasz się każdemu dać wskaźnik do głównej.

Po co skoro główna jest singletonem?
Taki pseudo kod. A da sie inaczej osiagnac cos takiego?
class kreatorlogow{
wpis();
}

class menagerzasobow{
glownaklasa* wskaznik
...
wczytajzasoby();
};
menagerzasobow::wczytajzasoby(){
wczytywanie..
wskaznik.logi.wpis("jakies tam logi");
}

class glownaklasa{
menagerzasobow zasoby;
kreatorlogow logi;
}

@polygon a jak to zrobic jesli trzymam wszystkie klasy w jednym pliku zrodlowym? I co to oznacza "wyciagnij foo.h"

Offline lgromanowski

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

# Lipiec 20, 2012, 21:04:10
@polygon a jak to zrobic jesli trzymam wszystkie klasy w jednym pliku zrodlowym? I co to oznacza "wyciagnij foo.h"
Rozbij na kilka plików, lub sprawdź dokładnie kolejność klas w pliku. Pisząc "wciągnij", miałem na myśli użycie dyrektywy preprocesora "#include" (która jest poniżej komentarza).

Offline Avaj

  • Użytkownik

# Lipiec 20, 2012, 21:11:35
Problem u ciebie jest taki, że manager zasobów nie potrzebuje dostępu do klasy głównej. Potrzebuje loggera, więc możesz go przekazać np. przy tworzeniu managera:

class logger
{
  void log();
}

class resmanager
{
  Logger* logger;

  resmanager(logger* logger)
  {
    this->logger = logger;
  }
}

class klasaglowna
{
  resmanager* resman;
  logger* logger;
 
  klasaglowna()
  {
    logger = new logger;
    resman = new resmanager(logger);
  } 

  ~klasaglowna()
  {
    delete resman;
    delete logger;
  }
}

Offline Santor

  • Użytkownik

# Lipiec 20, 2012, 21:36:51
Sam dokonca jeszcze nie wiem jakie klasy bd musialy miec dostep do menagera wiec robia tak na przyszlosc. Zeby uniwersalnie bylo.

Offline Oti

  • Użytkownik

# Lipiec 20, 2012, 21:38:59
Taki pseudo kod. A da sie inaczej osiagnac cos takiego?
class kreatorlogow{
wpis();
}

class menagerzasobow{
glownaklasa* wskaznik
...
wczytajzasoby();
};
menagerzasobow::wczytajzasoby(){
wczytywanie..
wskaznik.logi.wpis("jakies tam logi");
}

class glownaklasa{
menagerzasobow zasoby;
kreatorlogow logi;
}

@polygon a jak to zrobic jesli trzymam wszystkie klasy w jednym pliku zrodlowym? I co to oznacza "wyciagnij foo.h"
Nadal nie rozumiem problemu.

.h:
class kreatorlogow{
wpis();
}

class menagerzasobow{
glownaklasa* wskaznik
...
wczytajzasoby();
};

class glownaklasa{
menagerzasobow zasoby;
kreatorlogow logi;
}

extern glownaklasa GlownaKlasa;

.cpp:
glownaklasa GlownaKlasa;

menagerzasobow::wczytajzasoby(){
wczytywanie..
GlownaKlasa.logi.wpis("jakies tam logi");
}

Sam dokonca jeszcze nie wiem jakie klasy bd musialy miec dostep do menagera wiec robia tak na przyszlosc. Zeby uniwersalnie bylo.
Niech wszystkie mają, po co sobie komplikować życie.

Offline Santor

  • Użytkownik

# Lipiec 20, 2012, 22:06:33
Na moje chyba prosciej zrobic zeby kazda klasa miala jeden ten sam wskaznik go glownego obiektu niz wszystkie klasy do wszystkich ktore potrzebuja.
co to za słowo kluczowe "extern"? Juz wygoglowalem
« Ostatnia zmiana: Lipiec 20, 2012, 22:13:41 wysłana przez Santor »

Offline Oti

  • Użytkownik

# Lipiec 20, 2012, 22:30:50
Na moje chyba prosciej zrobic zeby kazda klasa miala jeden ten sam wskaznik go glownego obiektu niz wszystkie klasy do wszystkich ktore potrzebuja.
co to za słowo kluczowe "extern"? Juz wygoglowalem
Nie wiem o czym mówisz. Ty sam chyba zresztą też nie.

Offline Santor

  • Użytkownik

# Lipiec 20, 2012, 22:50:56
Dobra rozwiazalem sprawe po dogłębnej analizie. Na chłopski rozmu to trzeba tak(jakby ktos taki jak ja tu po pomoc zajrzał:))class glownaklasa; // tylko wstepna definicja
class kreator{
int pole1;
void jakasmetoda();//sama deklaracja metody

};
class zasoby{
int jakiespole;

void jakasmetoda(); //sama deklaracja metody
};
class glownaklasa{//definicja klasy
kreator logi;
zasoby jakieszasoby;
}
void kreator::jakasmetoda(){//dopiero po definicji glownej klasy, definiujemy funkcje klas skladowych.
...
}


:
i smiga, dzięki:)

Offline Veldrin

  • Użytkownik

# Lipiec 21, 2012, 01:14:51
Ale w takim razie po co mówisz o singletonie? Chyba nie przekazujesz wskaźnika do Singletona?