[C++] Przekazywanie sterowania

Piszę program obiektowo w C++ w którym mam klasę, której funkcje wyświetlają poszczególne Menu w programie (całość jest pod konsolę).

Wywołuję funkcję obiektu z funkcji main()

obiekt_w_ktorym_są_funkcje_wyswietlające_menu.WyswietlMenuG();

Poruszanie się po menu jest zrobione w pętli while(1) - pobieram znak z klawiatury i odpowiednia opcja jest podświetlana. Gdy ktoś wciśnie enter funkcja MenuGlowne odpalana inna funkcje (np. WyswietlMenuP())

Gdy użytkownik wybierze już wszystkie parametry, chciałbym żeby sterowanie wróciło do funkcji main() i jedna ze zmiennych z obiektu została przekazana do konstruktora innego obiektu.

Czy ktoś wie jak to zrobić?

Robisz break i wychodzisz z tej pętli do main().

Ale przydałoby się więcej info, jakiś kod etc.

#include 

using namespace std;


struct Menu;

void submenu(const Menu*);

void crt(const Menu*) { cout<<"Create something"<
void add(const Menu*) { cout<<"Add something"<
void del(const Menu*) { cout<<"Delete something"<
void rptvert(const Menu*) { cout<<"Show verticaly"<
void rpthorz(const Menu*) { cout<<"Show horizontaly"<
void load(const Menu*) { cout<<"Load from file"<
void save(const Menu*) { cout<<"Save to file"<

const struct Menu { const char *text; void (*fun)(const Menu*); const Menu *sub; }

  RptMenu[]=

    {

     {"Pionowo",rptvert},

     {"Poziomo",rpthorz},

     {"Wroc"},

    },

  MainMenu[]=

    {

     {"Nowy",crt},

     {"Dodaj",add},

     {"Usun",del},

     {"Pokaz (sub)",submenu,RptMenu},

     {"Wczytaj z pliku",load},

     {"Zapisz do pliku",save},

     {"Koniec"},

    }

  ;


void submenu(const Menu *menu)

  {

   cout<
   while(true)

     {

      cin.sync();

      unsigned n=0;

      const Menu *tmp=menu;

      while(tmp->fun) cout<<(++n)<<": "<<(tmp++)->text<
      cout<<"0: "<text<
      unsigned m;

      if((cin>>m)&&(m<=n))

        {

         if(!m) break;

         const Menu *tmp=menu+m-1;

         tmp->fun(tmp->sub);

        }

      else

        {

         cin.clear();

         cout<<"Nie ma takiej opcji"<
        }

     }

   cout<
  }


int main()

  {

   submenu(MainMenu);

   return 0;

  }

Obczaj to - bardzo łatwo się przerabia na klasy.

Tylko program będzie już w innej pętli bo z funkcji wyświetlającej jedno menu jest wywołanie innych

Kod:

Funkcja main:

int _tmain(int argc, _TCHAR* argv[])

{


	MenuGlowne tytan;

	tytan.WyswietlG();


	return 0;

}

Funkcja WyswietlG:

void MenuGlowne::WyswietlG(void)

{

	while(1)

	{

		bialy();

		system("cls");

		printf("\t\t SSSS kk\n");

		printf("\t\t SS SS kk\n");

		printf("\t\t SS SS kk\n");

		printf("\t\t SS nnnnn aaaa kk kk eeee\n");

		printf("\t\t SSS nn nn aa aa kk kk ee ee\n");

		printf("\t\t SSS nn nn aaaa kkkk eeeeee\n");

		printf("\t\t SS nn nn aa aa kkk ee\n");

		printf("\t\t SS SS nn nn aa aa kkkk ee\n");

		printf("\t\t SS SS nn nn aa aa kk kk ee ee\n");

		printf("\t\t SSSSS nn nn aaaaa kk kk eeee\n\n\n");	



		if(m==1){magnetowy();}printf("\t\t\t\t ROZPOCZNIJ GRE \n");bialy();

	    if(m==2){magnetowy();}printf("\t\t\t\t MENU OPCJI \n");bialy();

	    if(m==3){magnetowy();}printf("\t\t\t\t WYJSCIE \n");bialy();

		z = _getch();


		if(z == 72){m--;}

		if(m == 0){m =+ 3;}

		if(z == 80){if(m<3){m++;}} // Ograniczenie z dołu


		if((z == 13) && (m == 3)) exit(0); // Wyjście z programu

// if((z == 13) && (m == 2)) Opcje(); // Menu opcji

		if((z == 13) && (m == 1)) WyswietlP(); // Wyswietlenie menu wyboru poziomu trudnosci

	}



}

Dzięki, jutro jak będę miał jaśniejszy umysł to obczaję:) – Dodane 14.06.2012 (Cz) 15:42 – Staram się zrobić to tak jak pokazał alex ale mam pewne problemy z konstruktorem klasy Klasa:

class MenuR

{


private:

	const char *text; 

	void (*fun)(const MenuR*); 

	const MenuR *sub;


public:


	void WyswietlMenu(const MenuR *menu);

	MenuR(void);

	MenuR(const char, const MenuR);

	~MenuR(void);

};

Konstruktor: Znakami zapytania zaznaczyłem miejsce w którym nie wiem jaki typ danych wpisać. Nie bardzo wiem o co chodzi z tymi dwoma nawiasami obok siebie

MenuR::MenuR(const char *tekst, ??????, MenuR *nastepne_menu)

{

	const char *text=tekst; 

//	void (*fun)(const MenuR*)= funkcja; 

	const MenuR *sub = nastepne_menu;


}

Tak czy inaczej, jeżeli chcesz robić tego typu program-grę, na pewno będziesz miał jedną główną pętlę w main() (tzw. pętla czasu rzeczywistego), w której będą kręciły się inne pętle:

void main()

{

   while(true) // pętla czasu rzeczywistego

   {

      Ustawienia ustawienia = PetlaMenu();

      PetlaGry(ustawienia);    

   }

}


Ustawienia PetlaMenu()

{

   while(czySkonczonoUstawienia)

   {

      //pętla w której użytkownik sobie ustawia różne rzeczy,

      //które przypisujesz do obiektu klasy Ustawienia

   }

}


void PetlaGry(Ustawienia ustawienia)

{

   while(czyGraSkonczona)

   {

       //pętla w której grasz, korzystając z ustawień

   }  

}

ThaRealiestJEDI, mylisz Menu z MenuItem - w moim kodzie struktura Menu to element menu, dopiero tablica elementów stanowi menu.

W przypadku klasy opłaca się pakować elementy menu w listę jednokierunkową.

Elementy menu lepiej zrobić jako klasę wewnętrzną.

Ok ale tablice elementów tworzysz na podstawie struktury, czyli jest to tablica struktur tak?

Każde menu to osobna tablica struktur ‘Menu’. Czyli z tego co widzę powinno wystarczyć zamienić strukturę na klasę i zrobić odpowiedni konstruktor.

Dodane 15.06.2012 (Pt) 21:13

Ok, już wiem gdzie namieszałem wcześniej. Źle przypisywałem zmienne w konstruktorze (oj trzeba solidnie odświeżyć programowanie obiektowe).

W każdym razie przerobiłem kod tak żeby ze struktur otrzymać klasy i ogólnie wygląda to tak:

#include "StdAfx.h"

#include 


using namespace std;


class MenuZ;

void submenu(class MenuZ *menu);

void crt(class MenuZ*) { cout<<"Create something"<
void add(class MenuZ*) { cout<<"Add something"<
void del(class MenuZ*) { cout<<"Delete something"<
void rptvert(class MenuZ*) { cout<<"Show verticaly"<
void rpthorz(class MenuZ*) { cout<<"Show horizontaly"<
void load(class MenuZ*) { cout<<"Load from file"<
void save(class MenuZ*) { cout<<"Save to file"<

const class MenuZ { 

public:

	const char *text; 

	void (*fun)(class MenuZ*); 

	class MenuZ *sub; 

};





void submenu(class MenuZ *menu)

  {

   cout<
   while(true)

     {

      cin.sync();

      unsigned n=0;

      class MenuZ *tmp=menu; //tmp wskazuje na MenuZ ktore zostalo przekazane do funkcji

      while(tmp->fun) cout<<(++n)<<": "<<(tmp++)->text<
      cout<<"0: "<text<
      unsigned m;

      if((cin>>m)&&(m<=n))

        {

         if(!m) break;

         class MenuZ *tmp=menu+m-1;

         tmp->fun(tmp->sub);

        }

      else

        {

         cin.clear();

         cout<<"Nie ma takiej opcji"<
        }

     }

   cout<
  }


int main()

  {

	MenuZ MainMenu;

	MainMenu.text="Dodaj";

	MainMenu.fun=add;

//	MainMenu.sub


	submenu(MainMenu*);



   return 0;

  }

Na razie bez konstruktora. Sprawdziłem czy przypisania działają i wszystko jest ok. Obecnie natrafiłem na dwa problemy: Kompilator nie chce zbudować programu z linijką:

submenu(MainMenu*);

i w jaki sposób tworzyć menu tak jak robione jest to tutaj:

RptMenuZ[]=

    {

     {"Pionowo",rptvert},

     {"Poziomo",rpthorz},

     {"Wroc"},

    },

  MainMenuZ[]=

    {

     {"Nowy",crt},

     {"Dodaj",add},

     {"Usun",del},

// {"Pokaz (sub)",subMenuZ,RptMenuZ},

     {"Wczytaj z pliku",load},

     {"Zapisz do pliku",save},

     {"Koniec"},

    }

  ;