Eli mikä olisi oikea tapa palauttaa olion ominaisuuksista esim. nimi, joka on tietotyypiltään string?
#include <iostream> #include <string> using std::string; using namespace std; class obj{ int x,y,id; bool selected; string name; public: string get_name (void) { return (name); } }; int main(void){ obj olli; printf("nimi on %s", olli.get_name()); return 1; }
Tämä johtaa virheilmoitukseen "cannot pass objects of non-pod". Ilmeisesti string-luokkaa ei pystytä johtamaan oliosta toiseen funktioon. En voi tässä tapauksessa käyttää cout-funktiota, koska ongelma tuli vastaan Allegro-kirjaston textprintout -funktiota käytettäessä, joka on ilmeisesti identtinen printf-funktioon.
Entä mitä ongelmia globaalit attribuutit aiheuttavat? Muistelen kuulleeni että globaaleja attribuutteja tulisi välttää, mutta en ole keksinyt muuta tapaa saada attribuutteja näkymään kaikkien funktioiden alla joissa niitä tarvitaan.
int tarkista_paljonko_rahaa() { rahat=x; return rahat; } int main(void) { int x=1200; printf("rahaa %d",tarkista_paljonko_rahaa()); return 1; }
Eikö muuttujaa x ole mahdollista johtaa toiseen funktioon ilman että se asetetaan globaaliksi? Arvon kuljettaminen funktion kutsumisen kautta ei tule kysymykseen jos kuljetettavia arvoja alkaa olemaan ~20-30... toisinsanoen onko mahdollista että arvot periytyisivät funktiolta toiselle, jolloin globaaleja attribuutteja voisi välttää?
Printf on C-kieltä. %s tarvitsee char-tyyppisen merkkijonon.
// printf("nimi on %s", olli.get_name()); printf("nimi on %s", olli.get_name().c_str());
Globaaleita attribuutteja pitäisi monien mielestä välttää, koska niihin voi vahingossa kirjoittaa jotakin. Jos kuitenkin tekee ohjelmansa huolella, niin eivät ne minusta mitään ongelmia aiheuta.
Onko täysin järkevää muistinvarauksen kannalta palauttaa string? En tuota tyyppiä tunne, mutta eikö se kaiken järjen mukaan aiheuta muistivuodon? No, minä käyttäisin joka tapauksessa osoitinta kyseiseen muuttujaan tai palauttaisin suoraan char*:n (return name.c_str()
)
Ei ole (tiettävästi) mahdollista saada arvoa näkymään monessa paikassa ilman, että se on globaali. Tietenkin jakamalla koodin useampaan tiedostoon tuon voi saada hoidettua (globaali näkyy vain siinä tiedostossa), tai sitten voi laittaa muuttujansa (ja funktionsa) omaan nimiavaruuteen (namespace) tai tehdä (staattisen) luokan, joka sisältää nuo muuttujat ja funktiot. Yksi mahdollisuus on luoda arvoista struktuuri ja lähettää funktiolle viittaus siihen.
struct ArvoStruct { int x, y, z; // ... }; function Funktio(Arvostruct & Arvot) { if (Arvot.x == 10) printf("x = 10.\n"); Arvot.y = 100; } int main(void) { ArvoStruct Arvot; Arvot.x = 10; Funktio( & Arvot); printf("Arvot.y = %i\n", Arvot.y); // Arvot.y = 100 return 0; }
std::stringin palauttamisella ei saa aikaan muistivuotoa. Luokka sisältää destruktorit jotka pitävät huolen asiasta. Toinen tarina toki jos itse luo dynaamisen string-tyyppisen olion new:llä.
Korjattu versio:
#include <iostream> #include <string> using namespace std; class obj{ public: inline string get_name(); private: int x,y,id; bool selected; string name; }; // end obj // palauttaa nimen inline string obj::get_name() { return name; } // end get_name // ohjelman keskus int main( int argc, char *argv[] ) { obj olli; cout << "nimi on " << olli.get_name() << endl; return 0; } // end main
Miksi ihmeessä sekoitat c ja c++?
Pöh, en voi enää muokata edellistä viestiä. Tässä kuitenkin vähän parannettu versio:
#include <iostream> #include <string> using namespace std; class obj{ public: inline string get_name(); inline void set_name( string nimi); private: string name; }; // end obj // asettaa nimen inline void obj::set_name( string nimi ) { name = nimi; } // end set_name // palauttaa nimen inline string obj::get_name() { return name; } // end get_name // ohjelman keskus int main( int argc, char *argv[] ) { obj olli; olli.set_name("pitäähän muuttujille antaa arvotkin!"); cout << "nimi on " << olli.get_name() << endl; return 0; } // end main
Miksei muka voi korjata vanhat viestit? Typerää.
Aihe on jo aika vanha, joten et voi enää vastata siihen.