int i,i2; int mobamount=0; class Mob { public: string name; int id; int str; int hp, maxhp; int x,y; int Attack(int); }; //-------------------------------------- //-------------------------------------- for (i=0; i<6; i++) { Mob vihu[i]; vihu[i].id=mobamount++; mobamount=vihu[i].id; vihu[i].name="Vihu" + i; vihu[i].x=100; vihu[i].y=200; vihu[i].maxhp=(rand() %20) + 100; vihu[i].hp=vihu.maxhp; vihu[i].str=(rand()%10) + 5; }
Eli, olisiki classeja mahdollista käyttää niin, että tuo vihu olisi mahdollista tunnistaa tuosta hakasulkujen sisällä olevasta luvusta?
Toivottavasti joku ymmärsi koska en tuota nyt selvemmin osaa selittää :/
Saataa kuulostaa hiukan oudolta, mutta en tajunnut ongelmaa ensinkään. Mitä tässä on tarkoituksena tehdä? Ilmeisesti olet luonut luokan mob, (struct olisi riittänyt), jonka jäseniä yrität tallentaa vihu -taulukkoon. Miksi muuten Suomea ja Englantia samassa ohjelmassa?
Hmm... Siis tarkoitus olisi käyttää classia niinkuin Visual Basicin typejä eli esim. Vihu[1]:n nimeksi voisi vaihtaa "jalka" esimerkiksi tällä tavalla:
Vihu[1].name="Jalka";
Ja esim. Vihu[72]:n str:n voisi vaihtaa näin:
Vihu[72].str=32;
Toivottavasti selvensi ;)
Voitko kertoa ihan okeasti mitä haluat tehdä, koska Vihu[1].name="Jalka"; on mahdollista tehdä. Vihu[72].str = 32; on ihan yhtä laillinen. Tietysti sillä vaatimuksella, että on olemassa jokin luokka, josta luotu Vihu niminen taulukko, sekä juossa on olemassa public määreellä olevat muuttujat name ja str.
Voitko antaa esimerkin miten tuo tehdään? En itse onnistu tuossa..
Varmaankin jotenkin näin.
#include <iostream> class Mob { public: std::string name; int id; int str; int hp, maxhp; int x,y; int Attack(int); }; int main(){ Mob Vihu[100]; /* Muutetaan toisen jäsenen name arvoksi 'jalka' */ Vihu[1].name="Jalka"; /* Muutetaan indexin 72 str arvoksi 32 */ Vihu[72].str = 32; std::cout << Vihu[1].name << std::endl; /* Pitäisi olla 'Jalka' */ std::cout << Vihu[72].str << std::endl; /* Pitäisi olla 32 */ return 0; }
Oikeasti muuttujien tulisi olla private / protected muodossa, sekä luokalla voisi olla määriteltynä muodostin.
Mob vihu[6]; // Vihollistaulukko tulee luoda silmukan ulkopuolella! for (i=0; i<6; i++) { // ID:tä ei tarvita vaan hakasulkujen sisällä oleva indeksi vastaa sitä vihu[i].name="Vihu" + i; vihu[i].x=100; vihu[i].y=200; vihu[i].maxhp=(rand() %20) + 100; vihu[i].hp=vihu.maxhp; vihu[i].str=(rand()%10) + 5; } Vihu[1].name="Jalka"; Vihu[5].str=32;
Tämän pitäisi toimia!
Itse kysymystä en ymmärtänyt, koska jos viholliset ovat taulukossa, saat tietenkin aina viitattua taulukon indeksillä siihen viholliseen, ja indeksin voit tallentaa kuhunkin yksilöön vaikka for-silmukassa.
(Edit. Jaa, täällä ehdittiinkin jo jutella aiheesta. Ilmeisesti siis ongelmana tosiaan oli tuo taulukon sijoittelu koodissa? Kannattaa lukea tämä viesti silti.)
Sen sijaan koodisi näytti muilta osin aika jännittävältä. Tutkitaanpa pikaisesti, mitä se tekee, sikäli kuin kääntäjä sen kelpuuttaa. Yksinkertaisuuden vuoksi tehdään vielä vähän pelkistetympi esimerkkiluokka:
#include <iostream> using namespace std; class A { int id; public: A() { // Laitetaan juokseva numero jokaiselle luodulle oliolle. static int lkm; ++lkm; id = lkm; cout << "A " << id << " luotu!\n"; } ~A() { cout << "A " << id << " tuhottu!\n"; } void print() { cout << "print: id " << id << ".\n"; } }; int main() { int i; for (i = 0; i < 4; ++i) { std::cout << "\n" << "Kierros " << i << "\n"; A taulu[i]; taulu[i].print() } }
Kierros 0 print: id 134520352. Kierros 1 A 1 luotu! print: id 134514128. A 1 tuhottu! Kierros 2 A 2 luotu! A 3 luotu! print: id -1078563336. A 3 tuhottu! A 2 tuhottu! Kierros 3 A 4 luotu! A 5 luotu! A 6 luotu! print: id 134514507. A 6 tuhottu! A 5 tuhottu! A 4 tuhottu!
Ei tainnut osua ihan nappiin?
Palataanpa kielen perusteisiin.
Mob vihu[i];
Tässä luodaan taulu nimeltä vihu, jonka alkion tyyppi on Mob ja jossa on i alkiota. Standardin mukaan i ei saa olla muuttuja, ja tämän takia esitetyt koodit eivät välttämättä edes kääntyisi kaikilla kääntäjillä.
Taulukon alkiot indeksoidaan nollasta alkaen. Jos siis alkioita on i, viimeisen indeksi on i-1. Tämä selittää, miksi esimerkkikoodi tulostaa aivan kummallisia id-numeroita: kohdassa i ei ole oliota! Jossain tapauksessa ohjelma voisi vastaavan virheen takia kaatua, mikä sinänsä on aina hyvä asia, koska tällöin virhe on helpompi löytää.
Jos käytät GCC:tä (Windowsilla MinGW:tä, jonka saa Dev-C++:n tai Code::Blocksin mukana), laita käännösasetuksiin -std=c++98 -Wall -pedantic ja katso aina, mitä ilmoituksia tulee. Tällä tavalla vältät jo huomattavan määrän selviä virheitä.
Kun olet päässyt näistä virheistä yli, voit vaikka yrittää hieman valottaa, mikä on ongelmasi ja mitä haluat saada aikaan. Sitä odotellessa voit ihmetellä vaikka tätä koodia:
#include <map> int make_unique_id() { static int counter; return counter++; } class A { int id; // Osoittimet kaikkiin luokan ilmentymiin id:n mukaan static std::map<int, A*> a_map; public: // Luodessa tehdään id ja säilötään osoitin A(): id(make_unique_id()) { a_map[id] = this; } // Estetään kopiointi, ettei tule samaa id:tä monelle (voisi toki generoida uuden id:n) A(A const& t) throw() { throw "A(A const&): copying is not allowed!"; } // Tuhotessa poistetaan osoitinkin ~A() { a_map.erase(id); } // Normaali funktio id:n hakuun int get_id() { return id; } // Staattinen funktio, joka hakee osoitinkartasta id:n perusteella osoittimen. static A& get(int id) throw() { if (a_map.find(id) == a_map.end()) { throw "A::get(int): bad id!"; } return *a_map.find(id)->second; } }; // Staattinen taulukko vielä toistamiseen std::map<int, A*> A::a_map; #include <iostream> void test() { // Testikoodi. Luodaan a, haetaan funktiolla se uudestaan ja tarkistetaan, että tuli sama id takaisin. A a; if (A::get(a.get_id()).get_id() != a.get_id()) { throw "bug!"; } } int main() { try { test(); return 0; } catch (const char *msg) { std::cerr << "Error: " << msg << "\n"; return 1; } }
Jep, elikkäs sain tämän ongelman korjattua pienten koodin muokkailujen jälkeen. Kiitos kaikille vastanneille!
Aihe on jo aika vanha, joten et voi enää vastata siihen.