Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Oliot funktion sisällä

karvinen [21.06.2022 20:47:55]

#

Minulla on luokka pelaajat.
Siellä on funktio, mitä kutsutaan.

Pelaajat Juha;
Pelaajat Jakaja;

Juha.Laske();

void Pelaajat::Laske(){

// Mitä tänne?

}

Tässä saan muuttujan Pisteet tulemaan, mutta jos haluan saada täällä sisällä Jakajan Pisteet, niin pystyykö sen tekemään jotenkin helpommin, kun hakea muistipaikan osoitteen ym?

karvinen [21.06.2022 20:58:33]

#

Epätoivoisesti yritin funktion sisälläkin kutsua toista funktiota, mutta olisi ollut liian helppoa :D

int Pelaaja::JakajanPisteet()
{
	return Jakaja.Pisteet;
}

vehkis91 [22.06.2022 08:59:29]

#

Hei,

Mikäli oikein ymmärsin ongelmasi: eli haluat jakajan pisteet näkymään, kun kutsut pelaaja.Laske(); -funktiota?

Tuohon yksinkertaisin ratkaisu on antaa funktiolle paramaterina viittaus Pelaaja-tyyppiseen olioon.

void Pelaaja::Laske(const Pelaaja& toinen)
{
 //Esim pisteiden lasku yhteen
 this->pisteet += toinen.pisteet;
}

Tosin itse tekisin ehkä vähän eri tavalla tuon, mutta tämä lienee vastaa kysymykseesi.

Mikäli taas haluat vertailla pelaajan ja jakajan pisteitä, kannattanee tehdä kokonaan erillinen funktio, joka ei ole sidottu luokkaan:

int vertaa (const Pelaaja &eka, const Pelaaja &toka)
{
 if ( eka.pisteet > toka.pisteet )
   return 1;
 else if ( eka.pisteet < toka.pisteet )
   return 2;
//Jos samankokoset nii palauttaa 0.
 return 0;
}

Koodissa saattaa olla virheitä, koska puhelimella kirjoitettu, mut ehkä ideasta saa kiinni.

Metabolix [22.06.2022 11:15:46]

#

Tuossa alkuperäisessä koodissa on nyt jokin perustavanlaatuinen suunnitteluvika. Missään tapauksessa luokkaan ei kuulu tehdä omaa funktiota jokaisen erillisen olion arvojen hakemiseen (kuten JakajanPisteet ja JuhanPisteet). Tuostahan seuraa järjenvastainen tilanne, jossa voi kirjoittaa Juha.JakajanPisteet(), joka ei koske Juhaa millään tavalla. Olio-ohjelmoinnin Juhan pitää sisältää vain Juhaa koskevia asioita. (Tietenkin aina on poikkeustilanteita.)

Luokan nimen pitäisi olla varmaan Pelaaja, jos se kuvaa yhtä pelaajaa. Pelaaja-luokan sisällä käsitellään vain aina kyseistä yksilöä. Sen sijaan, että pisteet haettaisiin kutsuilla JakajanPisteet() ja JuhanPisteet(), pitäisi yleensä olla vain yksi funktio, jota voi kutsua kummallekin oliolle: Jakaja.HaePisteet() ja Juha.HaePisteet(). Eli olio-ohjelmoinnin kannalta oikea koodi olisi enemmänkin tällainen:

#include <iostream>

class Pelaaja {
  int pisteet;
public:
  int HaePisteet() const {
    return pisteet;
  }
};

Pelaaja Juha, Jakaja;

int main() {
  std::cout << "Juhan pisteet: " << Juha.HaePisteet() << "\n";
  std::cout << "Jakajan pisteet: " << Jakaja.HaePisteet() << "\n";
}

Jos samaan aikaan tarvitaan Juhan ja Jakajan pisteitä, tämä yleensä tehtäisiin joko uudella parametrilla tai luokan ulkopuolisella funktiolla, kuten vehkis91 yllä esittää.

Siis käytännössä ratkaisu voisi olla jompikumpi seuraavista:

Juha.LaskeJotain(Jakaja.Pisteet);
LaskeJotain(Juha.Pisteet, Jakaja.Pisteet);

karvinen [22.06.2022 13:09:04]

#

Suuret kiitokset avusta, olipas tuo kätevä tapa viitata siihen.

Tässä nyt muutaman kuukauden vääntänyt c++ ohjelmointi kurssia ja ilmeisesti ihan liikaa yritti asioita tehdä tietyllä kaavalla.

Ei käynyt mielessäkään, että funktion voi tehdä luokan ulkopuolelle, niin sinne voi viittailla kuinka haluaa.
Tämän kohdan, kun luin, niin kyllä tuli tyhmä olo, yritin vaan miettiä, että miten se onnistuu siellä jo kutsutun funkton sisällä :D

Taas oppii paljon uutta, kiitos.

Vastaus

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

Tietoa sivustosta