SuomiGameHUB

Maailma tarvitsee pelejä

C++ osoittimet, eli pointterit

C++ on tarjoaa kehittyneitä ominaisuuksia, kuten osoittimia, jotka ovat erittäin hyödyllisiä mutta voivat olla haastavia ymmärtää. Osoittimet mahdollistavat suoran pääsyn muistin alueille, mikä on hyödyllistä mutta vaatii tarkkuutta. Tämä ominaisuus erottaa C++:n monista muista kielistä, kuten C#:sta, joka hallitsee muistia automaattisesti.

Yksi C++:n keskeisistä konsepteista on olio-ohjelmointi. Kun C++:ssa luodaan olio ja lähetetään se funktiolle, kieli luo kopion oliosta, ei vain viitettä siihen. Tämä eroaa C#:n toiminnasta, joka luo automaattisesti osoittimen lähetettäessä oliota funktiolle. C++:ssa jokaisella funktiokutsulla luodaan uusi olio, joka voi sisältää runsaasti tietoa ja metodeja. Tämä voi johtaa merkittävään muistinkäyttöön, erityisesti jos luokat ovat suuria ja monimutkaisia.

Kopiointiongelma

Kun puhutaan olioiden kopiointiongelmasta C++:ssa, tulee esille muistinhallinnan merkitys. Jos esimerkiksi luodaan ‘HeiMaailma’-tyyppinen olio, jolla on useita muuttujia ja metodeja, sen kopioiminen funktiokutsujen yhteydessä voi kuluttaa paljon muistia. Tämä muistinkäyttö kasvaa eksponentiaalisesti, kun oliot sisältävät monimutkaisia rakenteita, kuten muita olioita, tietorakenteita tai suuria tietomääriä. Jos pelissä on useita tällaisia olioita, jokaiselle luodaan uudet kopiot, jolloin muistinkäyttö voi kasvaa hallitsemattomaksi.

Ongelma korostuu, kun otetaan huomioon, että C++ ei vain kopioi oliota, vaan kaikki sen sisältämät tiedot ja alkiot on kopioitava uuteen olioon. Jos olio sisältää esimerkiksi ‘Pelaaja’-luokan olioita, koordinaatteja, tekstuuritietoja ja muita resursseja, kaikki nämä on luotava uudelleen joka kerta, kun olio lähetetään funktiolle. Tämä johtaa paitsi muistinkäytön kasvuun myös suorituskyvyn heikkenemiseen, sillä järjestelmän on käsiteltävä jatkuvasti suuria määriä tietoa.

Tässä kontekstissa pohditaan, miten voidaan välttää tarpeeton tietojen kopioiminen ja hyödyntää olemassa olevia olioita tehokkaammin. C++ tarjoaa ratkaisuja tähän ongelmaan, kuten osoittimien ja viittausten käyttöä. Osoittimien avulla voidaan viitata suoraan olemassa olevaan olioon sen sijaan, että kopioidaan koko olio. Tämä säästää sekä muistia että prosessointiaikaa, sillä järjestelmän ei tarvitse luoda ja hallinnoida useita kopioita samoista tiedoista.

Muistin perusidea on, että se on kuin taulukko, jossa jokaisella solulla on oma osoitteensa ja jokaisessa osoitteessa on arvo. Kun C++:ssa luodaan osoitin (pointer), se sisältää vain yhden muistiosoitteen, eli osoittimen koko on todella pieni. Esimerkiksi jos luodaan osoitin, joka viittaa olioon, osoitin tallentaa sen osoitteen, josta olio alkaa muistissa. Tämä mahdollistaa suoran pääsyn olion tietoihin ja metodeihin ilman tarvetta kopioida koko oliota.

Osoittimien käyttö

Osoittimen luominen C++:ssa tapahtuu määrittämällä ensin osoittimen tyyppi, joka vastaa viitatun olion tyyppiä. Tämän jälkeen käytetään tähti-merkkiä (*) ilmoittamaan, että kyseessä on osoitin, ja annetaan sille nimi, esimerkiksi ‘objektiPointteri’. Osoitteen asettaminen osoittimeen tapahtuu käyttämällä ‘et-merkkiä’ (&) ennen objektin nimeä. Näin osoitin saa objektin muistiosoitteen, eikä itse objektia.

#include "HeiMaailma.h"

void main()
{
  HeiMaailma objekti;
  HeiMaailma* objektiPointteri = &objekti;
  funktio(objektiPointteri);
}

Kun osoitin lähetetään funktiolle, funktion määritelmässä tulee olla tieto siitä, että odotetaan osoitinta. Jos funktiossa yritetään käyttää osoitinta kuin normaalia oliota, tulee virheilmoitus. Tämä johtuu siitä, että osoitin ei ole olio, vaan viittaus olioon. Olioon päästään käsiksi käyttämällä ‘nuoli’-operaattoria (->), joka kertoo, että halutaan päästä käsiksi osoittimen viittaamaan olioon ja sen tietoihin tai metodeihin.

void funktio(HeiMaailma* obj)
{
  obj->tulostaViesti();
}

Tämä osoittimien käyttö C++:ssa sallii ohjelmoijan hallita muistia tehokkaammin. Osoittimilla voidaan välttää tarpeettomat datan kopiointi ja hallita suuria tietorakenteita tehokkaammin. Osoittimien käyttö edellyttää kuitenkin tarkkuutta ja ymmärrystä muistinhallinnasta, koska virheellinen käyttö voi johtaa muistivuotoihin ja ohjelman epävakaisuuteen. Oikein käytettynä osoittimet ovat kuitenkin voimakas työkalu C++:n ohjelmoijan työkalupakissa.

Edellinen osa: C++ perusteet

Keskustelu

Aloita uusi keskustelu