Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: String-luokan palautus funktiosta (non-pod error)

Reaktor [19.08.2005 12:32:33]

#

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ää?

Aruviel [19.08.2005 13:17:30]

#

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());

Metabolix [19.08.2005 16:27:35]

#

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;
}

rutkis [22.08.2005 16:04:11]

#

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ä.

aWW [23.08.2005 10:21:35]

#

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++?

aWW [23.08.2005 13:57:40]

#

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ää.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta