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

Klasa okna, dźwięku - singleton czy coś innego? Jaka implementacja?

Object Storage Arubacloud
0 głosów
177 wizyt
pytanie zadane 29 października 2016 w C i C++ przez easytodo Mądrala (5,380 p.)

Witam serdecznie,

piszę pewną aplikację okienkową w C++ oraz SFML i zastanawiam się sposobem implementacji takich klas jak m.in. okno oraz dźwięk.

Klasy te będą używane w wielu innych klasach. Główna pętla mojego programu wygląda tak:

int main()
{
	Flashcards flashcards;
	Window window;
	
	IState* state = new StateMenu(flashcards,window);
	
	while(!state->toExit())
	{
		state->update();
		state->render();
		
		if (state->getStateMenu()) 
			state = new StateMenu(flashcards,window);
		
		else if (state->getStateOptions())
			state = new StateOptions(flashcards,window);
			
		else if (state->getStateManage())
			state = new StateManage(flashcards,window);
		
		else if (state->getStateStart())
			state = new StateStart(flashcards,window);
	}
	return 0;
}

Moja aplikacja jest podzielona na stany. Tak jak widać, za każdym razem muszę przesyłać obiekt flashcards oraz window do konstruktora stanu (a w przyszłości będę musiał przesyłać jeszcze obiekt klasy odpowiedzialnej za dźwięk i może coś jeszcze), poza tym, chcąc np. użyć klasy dźwięku w podklasach klasy State, znowu muszę obiekt przesyłać przez referencję - jest to bardzo niewygodne.

Właśnie tego przesyłania chcę uniknąć - Window, Flashcards oraz Sound będą miały tylko 1 instancję. 

Chciałbym używać tych 3 klas w dowolnej klasie należącej do mojego programu, bez potrzeby przesyłania doń obiektu - czy mam kombinować ze statycznością, stworzyć Singleton lub jeszcze coś innego? 

Co do Singletona, w jaki sposób miałaby wyglądać jego implementacja? W sieci nie znalazłem niczego co przybliżyło by mnie do znalezienia rozwiązania, może Wy znacie jakieś pomocne materiały?

Serdecznie pozdrawiam!

2 odpowiedzi

+1 głos
odpowiedź 29 października 2016 przez criss Mędrzec (172,590 p.)
wybrane 29 października 2016 przez easytodo
 
Najlepsza

Właśnie tego przesyłania chcę uniknąć - Window, Flashcards oraz Soundbędą miały tylko 1 instancję.

No to jednoznacznie nasuwa się singleton.

 Co do Singletona, w jaki sposób miałaby wyglądać jego implementacja? W sieci nie znalazłem niczego co przybliżyło by mnie do znalezienia rozwiązania, może Wy znacie jakieś pomocne materiały?

Serio? o_O http://4programmers.net/C/Artyku%C5%82y/Generyczny_singleton_w_C++ 

To jest taki szablon singletona, ale tobie wystarczy prywatny konstruktor i jakaś statyczna metoda zwracająca instancje (statyczny obiekt tworzony w tej metodzie) : 

class Singleton
{
   Singleton() { /* ... */ }

   /* reszta metod */

public:
   static Singleton & instance()
   {
       static Singleton a;
       return a;
   }
};

PS : Nie tak powinny wyglądać stany. Poczytaj o wzorcu State. I przeczytaj ten artykuł (magazyn Programista):

 https://www.dropbox.com/s/hutknzxtxafusdt/maszyna%20stanow.rar?dl=0

Ciekawy przykład, na pewno ci  rozjaśni.

komentarz 29 października 2016 przez easytodo Mądrala (5,380 p.)
Rozumiem to tak:

Przed moim mainem deklaruję singletona używając statycznej metody, na przykład static void init() ( Window::init(args) ) i to tworzy klasę z zapisanymi wartościami okna.

Następnie, w obojętnie jakim module programu, dajmy na to StateMenu.cpp, chcąc coś narysować, należy zrobić coś typu:
Window::getSingleton().draw(sf::Drawable&); ?
komentarz 29 października 2016 przez criss Mędrzec (172,590 p.)

Przed moim mainem deklaruję singletona używając statycznej metody, na przykład static void init() ( Window::init(args) ) i to tworzy klasę z zapisanymi wartościami okna.
 

Nie bardzo rozumiem.

 Następnie, w obojętnie jakim module programu, dajmy na to StateMenu.cpp, chcąc coś narysować, należy zrobić coś typu:
Window::getSingleton().draw(sf::Drawable&);

Tak. O ile twoja klasa ma metode draw ofc.

Ale powtarzam - przeczytaj artykuł, bo komplikujesz strukture programu. 

komentarz 29 października 2016 przez easytodo Mądrala (5,380 p.)

Przed moim mainem deklaruję singletona używając statycznej metody, na przykład static void init() ( Window::init(args) ) i to tworzy klasę z zapisanymi wartościami okna.

Chodzi mi o sposób nadania początkowych wartości (tutaj oknu), czyli na przykład przypisanie rozmiaru okna, głębii kolorów, nazwy okienka itd 

komentarz 29 października 2016 przez criss Mędrzec (172,590 p.)
Ustaw je w konstruktorze. Nie wiem o co ci chodzi bo zapis "static void init() ( Window::init(args) ) " nic nie znaczy. Nie wiem, zrób jak chcesz.
komentarz 29 października 2016 przez easytodo Mądrala (5,380 p.)
Po prostu nie do końca rozumiałem inicjację obiektu ale chyba już wszystko łapię, bardzo dziękuję za wyjaśnienie sposobu działania singletona jak i za artykuł o stanach, moje stany nie mają pewnie nic wspólnego z patternem stanu bo są wymyślone przeze mnie bez żadnych zewnętrznych źródeł, ale poczytam o wzorcu State i dokonam poprawek. Bardzo dziękuję za pomoc! :)
0 głosów
odpowiedź 29 października 2016 przez Munvik Dyskutant (9,350 p.)

Tak najlepszym rozwiązaniem jest singleton.

Stwórz w tej klasie gdzie jest obsługa stanów coś takiego:

class klasa
{
 static klasa *singleton;

public:
 klasa()
  {
  if(singleton == nullptr)
   {
    singleton = this;
   }
  }

 static klasa *get() 
  {
  return singleton;
  }
}
 

Do tego odpowiedni destruktor.

Jeszcze dorób w tej klasie metody odpowiadające za zmianę stanów, dzięki czemu będziesz mógł zmieniać stany ze wszystkich klas istniejących w twoim projekcie.

komentarz 29 października 2016 przez easytodo Mądrala (5,380 p.)

Dobra, ale jak później takiego singletona używać? Załóżmy:

Singleton odpowiadający za okno (rysowanie itd.)

Okno posiada metodę draw();

1) Co z resztą składowych? Teraz moja klasa okna wygląda w ten sposób:

#pragma once
#include <SFML/Graphics.hpp>

class Window
{
private:
	sf::RenderWindow window;
	int x;
	int y;
public:
	Window();
	~Window();
	sf::RenderWindow* getWindow();
	void closeWindow();
	void startRender();
	void finishRender();
	void draw(sf::Drawable&);
	int getX();
	int getY();
};

Czy wszystkie metody i składowe mają być static? 

2) Jak wygląda wywołanie np metody draw() w dowolnym module programu?
Czy coś podobnego do:
 

//plik StateMenu.h

#include "Window.h"
//...

class StateMenu
{
   Window *window = klasa::get();
   //...
};

I później używamy zmiennej window do obsługi okna? (np. window->draw() itd)?

 

komentarz 29 października 2016 przez criss Mędrzec (172,590 p.)
To nie jest singleton. Nie wiem co to jest, ale singleton ma gwarantować istnienie maksymalnie jednego obiektu klasy.
komentarz 29 października 2016 przez Munvik Dyskutant (9,350 p.)
easytodo

Możesz tak robić, nie ma problemu. Tylko musisz dokończyć klasę a mianowicie destruktor, żeby obiekt singleton nie wskazywał na nic (przypisujesz mu nullptr).

Podobne pytania

0 głosów
1 odpowiedź 454 wizyt
pytanie zadane 31 października 2022 w C i C++ przez Krzysztofs1234 Użytkownik (890 p.)
0 głosów
1 odpowiedź 342 wizyt
pytanie zadane 11 grudnia 2016 w C i C++ przez DragonCoder Nałogowiec (36,500 p.)
0 głosów
4 odpowiedzi 602 wizyt
pytanie zadane 10 kwietnia 2017 w C i C++ przez niezalogowany

92,573 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...