Jag skulle behöva hjälp med att komma igång. Det är lite svårt att se vad du gjort själv och inte. Är det en skoluppgifts beskrivning? Tack för svaret. Tänk objektorienterat: Jag har kommit en bit på väg.. Jag vet hur jag ska göra för att lägga in menyvalen i min vektor. 1. Njae, det där förstår jag inte riktigt... MenuItem behöver ingen information om Menu. Menu bestämmer vilket id MenuItem har, och vilken description det har. Jag måste tänka fel. Eller iallafall annorlunda. :) Hmm... du har lagt upp det lite dumt. Jag har utgått ifrån ett klassdiagram jag har gjort. Sådär. Jag har gjort ett fulhack, känns det som :P Har inte speciellt gott om tid, men jag tänkte nämna litegrann: Det var så här jag ville ha det:Menysystem med stack
Jag ska ha 3 klasser (plus subklasser):
Application
Menu
MenuItem
Det är i Application allt körs kan man säga.
Här har jag en stack med Menu-objekt: stack<Menu*> menus;
Det är alltså objektet överst på stacken som representerar den aktuella menyskärmen.
Menu hanterar logiken och grafiken.
Här finns en vektor med de olika val man kan göra på varje menyskärm:
vector<MenuItem*> menuItems;
Och två publika funktioner:
virtual unsigned int DoScreen() = 0;
void PrintMenuItems();
DoScreen() är menyerna update-funktion, den ritar alltså ut menyn på skärmen genom att anropa PrintMenuItems(). Den lyssnar också efter input från användaren.
Värdet skickas som instans till Application som i sin tur pushar/popar till stacken.
MenuItem representerar ett specifikt val i en specifik meny.
Privata variabler:
unsigned int id;
string description;
Till sist så behövs det subklasser till basklassen Menu.
Dessa ska också implementera funktionen DoScreen()
De ska representera de menyskärmar som programmet använder sig av.
Så här ska det funka:
Låt oss säga att vi har en meny som heter MainMenu, där valmöjligheterna är:
1. Start
2. Options
3. Quit
Om jag trycker 2 så ska Optionsmenyn lägga sig överst på stacken.
Och visa till exempel
1. Config
2. Difficulty
3. Exit
Trycker jag 3 så ska jag komma tillbaka till MainMenu.
Mycket text att gå igenom. Hoppas ni tar er tid för jag skulle verkligen vilja veta hur jag ska gå tillväga.
Var är det lämpligast att börja?
Hur ska jag göra för att få in valen i min vektor med MenuItem?
Tacksam för all form av hjälp.Sv: Menysystem med stack
Nåväl, det lättaste att börja med är väl uppifrån.
Application, den håller reda på menyerna mha stacken. Underst på stacken ligger basmenyn, och över den ligger undermenyer. Utifrån det perspektivet inser man att man inte behöver hålla reda på nånting gällande menyernas ordning, det sköter stacken själv. Alltså nånting i stil med att om du skulle vilja ändra position på det översta skulle du göra så här:
menus.top->position= ...
Utifrån det borde du väl åtminstone kunna börja skriva klasserna. Gör så här: skriv Application-klassen som om du redan hade skrivit "Menu".Sv:Menysystem med stack
Ja, det är en skoluppgift.
Det gick rätt lätt med att skapa klasserna, tills jag kom till MenuItem.
Denna klassen ska innehålla de olika valen man kan göra på varje meny.
Exemplet med Options
1. Config -> id = 1, desc = Config
2. Difficulty -> id = 2, desc = Difficulty
osv.
Dessa olika valen ska lagras som objekt i vektorn.
Men hur ska jag "bygga upp" klassen MenuItem?
Jag vet inte alls hur jag ska göra.Sv: Menysystem med stack
Vad är ett MenuItem?
Hur vill du kommunicera med det, vad kan det göra?
Egentligen inget, det är menyn som sköter funktionaliteten!
Vilka egenskaper har det?
Till att börja med har du ju de två givna; id och desc. Så släng in dem i private och gör åtkomstfunktioner åt dem, på det sättet du vill.
Nåväl - vad behöver du mer?
Rent spontant skulle jag säga att klassen inte behöver något mer. I och med att det är en ganska liten applikation så kan du låta dig ändra små delar av koden efterhand.
Den representerar alltså bara data, och skiljer det tydligt från logiken, ett trevligt sätt att hantera det på. Du skulle t ex kunna ha ikon, ljud och tooltip i klassen, och även funktioner för att göra "bestående val", dvs markering, etc.
Men i det här fallet räcker det med att ha det så för att menyn ska kunna få fram beskrivningen utifrån IDt enkelt.Sv:Menysystem med stack
Fast jag har fortfarande vissa problem.
1.
För att veta vilka menyval som ska visas, så måste jag veta vilket val personen har gjort i den första menyn.
Jag har en int menuChoice som ligger som protected i klassen Menu. Eftersom den ligger som protected så går det att nå den via subklasserna. I mitt fall bara MainMenu.
Jag har provat med att göra så här i MenuItem's konstruktor:
MainMenu *mainMenu;
mainMenu = new MainMenu;
Jag tänkte att på detta sättet så kan jag göra en funktion som returnerar menuChoice. Och på så vis få menyvalet.
Men det går inte att göra så här, programmet kraschar :O
Det är lite tamt med information, hoppas det går att få ut nåt av det. Fråga annars. :)
Frågan är alltså: Hur ska jag göra för att "få tag på" menyvalet?
2.
Det är rätt enkelt att få programmet att skriva ut vilka id som ska visas på varje menyskärm (Kör en for-loop).
Problemet här är att jag inte vet hur jag ska få rätt desc till rätt id.
Några förslag?
Tacksam för all hjälp :)Sv: Menysystem med stack
Jag skulle lagt upp MenuItems konstruktor så här: MenuItem::MenuItem (int id, string desc) : id_(id), desc_(desc) {}
Sen har du alla menyer i din application-klass, i stacken.
Alltså:
Application innehåller ett antal menyer (stacken håller reda på ordning etc., men det är Applications ansvar). Application ansvarar alltså bara för i vilken ordning menyerna finns etc., sen får menyerna själva rita ut sig etc.
Menu innehåller ett antal menuitem för att man ska slippa hårdkoda det, och för att man enkelt ska kunna byta ut de olika itemsen. I princip kan du också ha instruktioner (och vid närmare eftertanke är det nog meningen att du ska ha något i den stilen) för vad som ska hända vid det valet.
2. Ärligt talat är jag inte säker på vad du menar. Du har en meny Menu, där du har menyvalen som vector<*MenuItems>. Elementen får du ut med t.ex. något ur algorithm eller i värsta fall en egen loop. Där använder du typ EttItem->GetID() resp. EttItem->GetDesc().Sv:Menysystem med stack
Postar de viktiga delarna i koden, som den ser ut nu.// Programmets nav
void Application::Run()
{
menus.push(new MainMenu);
// Testa skriva ut stacken.
cout << endl << "STACK:" << endl;
menus.top();
cout << "STACK SLUT" << endl << endl;
}
// Konstruktor
MainMenu::MainMenu(void)
{
DoScreen();
}
unsigned int MainMenu::DoScreen()
{
Menu::PrintMenuItems();
cout << "Make choice: ";
cin >> menuChoice;
Menu::TheMenuChoice();
return menuChoice;
}
void Menu::PrintMenuItems()
{
menuItems.push_back(new MenuItem);
cout << "Menu: Main Menu" << endl;
cout << endl << "Vector:" << endl;
// Testa skriva ut vektorn
PrintVector();
cout << "Slut på vector" << endl;
}
// Konstruktor
MenuItem::MenuItem(void)
{
id = 1;
description = "";
}
void Menu::PrintVector()
{
for(vector<MenuItem*>::iterator it = menuItems.begin(); it != menuItems.end(); it++)
{
(*it)->PrintMenuChoices();
}
}
void MenuItem::PrintMenuChoices()
{
cout << id << ". " << description << endl;
}
void Menu::TheMenuChoice()
{
switch(menuChoice)
{
case 1:
{
cout << "Game Starts" << endl;
break;
}
default:
{
cout << "Wrong choice, try again" << endl;
break;
}
}
}
1. Jag vet inte hur jag ska lägga in värdena i vektorn. (Kalla mig trög :D)
Nu ligger där två värden: id = 1, description = "". Hur ska jag göra för att lägga in t ex. id = 2, description = "test" ?
Så att den skriver ut: 1.
2. test
2. Stacken är tom.
Sv: Menysystem med stack
Tänk så här: En klass är en beskrivning av ett objekt. Nu delar du upp dina (tre) objekt i resp. klasser.
Varje klass har ett antal metoder (i vissa fall även egenskaper), med vilka de kommunicerar med omvärlden. Dessa är mycket strikt definierade; de skall utföra en viss sak, utföra den rätt och bara den saken. Ex: Application::Run ska hantera menyer, vilket innebär: visa menyer, ta emot meddelanden från dem, skicka meddelanden till dem, stänga dem.
Börja med det: skriv upp varje klass namn och dess syfte, följt av metodernas namn och deras syfte - i ord!
Ha även med konstruktorer och destruktorer.
Förrän det är klart är det ingen större poäng att börja koda. (Förmodligen kommer du kunna behålla en hel del kod, men det får man vänta med.)
Grejen är att jag ser att du skapar objekt i konstruktorer som inte borde skapas där, etc., så vi måste börja en bit bakåt.Sv:Menysystem med stack
Fast jag vet inte hur jag ska lägga upp konstruktorerna/destruktorerna.
Kan ju skriva ned allt här om du känner för att kommentera nåt. :)
Application : Håller reda på vilken meny som ska visas på skärmen genom att använda sig av en stack. Objektet överst på stacken är den aktuella menyskärmen.
- Run() : Innehåller programmets "huvudloop". Pushar/popar rätt meny till stacken.
Menu : Hanterar logiken och "grafiken"
- virtual unsigned int DoScreen() = 0 : Menyernas huvudsakliga update-funktion. Lyssnar efter input.
- PrintMenuItems() : Skriver ut menyn på skärmen.
MainMenu:Menu : Representerar menyskärmen "MainMenu"
- unsigned int DoScreen() : Update-funktion. Lyssnar efter input.
Options:Menu : Representerar menyskärmen "Options"
- unsigned int DoScreen() : Update-funktion. Lyssnar efter input.
MenuItem : Representerar spcifikt val i specifik meny. De olika val som kan göras vid varje menyskärm.Sv: Menysystem med stack
Men jag dras fortfarande med samma problem med MenuItem.
Jag tycker att den klassen är väldigt onödig. Visst man kan lägga vanliga cout för att skriva ut respektive menyval.
Men jag behöver använda mig av de privata variablarna: id och description.
Hur ska jag göra det?
Tar ett exempel:
MainMenu skrivs ut:
1. Start Game // id = 1, description = Start Game
2. Options // id = 2, description = Options
3. Exit // id = 3, description = Exit
Jag fattar inte hur jag ska göra den utskriftskoden. Några tips?Sv:Menysystem med stack
1. Konstruktorer och destruktorer:
En konstruktor skall konstruera ett objekt, inget annat. Alltså ska man lägga in allt som måste skapas eller initieras så fort objektet skapas i konstruktorn, inget annat. Det såg ut som om du ville ha en del logik i konstruktorn, undvik allt för mycket sådant.
2. MenuItem:
Det beror på hur man ser det. Fördelen med att lägga varje alternativ som ett eget objekt är att du lätt kan utvidga dem. Du kan som sagt utöka klassen med grafik, ljud, beteenden etc. Du bara skiljer bort alternativens innehåll osv. från deras funktion.
Det lättaste sättet att få ut ID och desc är att göra en getID() resp. getDesc(), alternativt print() eller en operator>>Sv: Menysystem med stack
MenuItem::MenuItem(int theId, string theDescription)
{
id = theId;
description = theDescription;
}
Det var följande kod jag menade med: "..rätt desc till rätt id":menuItems.push_back(MenuItem(1, "Start Game"));
menuItems.push_back(MenuItem(2, "Options"));
menuItems.push_back(MenuItem(3, "Exit"));
Tack för alla svar.