Prev Next Up Title Contents Index

Olio parametrina

Koska arvoparametrin välityksessä täytyy välitettävästä parametrista tehdä tilapäinen kopio, kutsutaan olioparametrin kohdalla silloin tietysti aliohjelman loppuessa tilapäisen olion hävittäjää.

Jos aliohjelman aikana on oliolle tehty jotakin, jota ei saisi hävittää, menevät nämä sen sileän tien aliohjelman loppuessa. Erityisesti dynaamista muistia käsittelevien olioiden kanssa saa olla tarkkana. Siispä useimmiten onkin parempi välittää olion osoite tai referenssi kuin olio itse.

Seuraavassa malli ongelmasta:

objectar.cpp - olion välittäminen arvoparametrina ja sen ongelmat

	/* OBJECTAR.CPP - olion välittäminen arvoparametrina */
	#include <stdio.h>
	#include <string.h>
	
	class cJono {
	  int max_pit;
	  char *s;      // Yksinkertaistamiseksi tarkistukset puuttuvat!
	public:
	  cJono(int koko=255) {
	    s = new char[koko+1]; s[0]=0; max_pit = koko;
	    printf("Oletusrakentaja: "); tulosta();
	  }
	  cJono(const char *is) {
	    max_pit = strlen(is);
	    s = new char[max_pit+1];
	    strcpy(s,is);
	    printf("Rakentaja: "); tulosta();
	  }
	  ~cJono() {
	    printf("Hävittäjä: "); tulosta();
	    if ( max_pit ) delete [] s; else printf("Oli jo tuhottu!\n");
	    max_pit=0;
	  }
	  void tulosta() const {
	    printf("Osoitteet: olio %p, jono %4p Jono %s\n",this,s,s);
	  }
	  friend int vertaa(cJono j1, cJono j2);
	  friend void ftulosta(cJono j);
	};
	
	
	int vertaa(cJono j1, cJono j2)
	{
	  printf("Aliohjelmassa vertaa!\n");
	  j1.tulosta(); j2.tulosta();
	  return strcmp(j1.s,j2.s);
	}
	
	void ftulosta(cJono j)
	{
	  printf("Aliohjelmassa ftulosta!\n");
	  j.tulosta();
	  printf("Pois aliohjelmassa ftulosta!\n");
	}
	
	int main(void)
	{
	  printf("\n---------------------------------------------------\n");
	  cJono j1("j1"), j2("j2");
	
	  printf("Menossa aliohjelmaan ftulosta:\n");
	  ftulosta(j1);
	  printf("Menossa aliohjelmaan tulosta:\n");
	  j1.tulosta();
	
	  printf("Vertailu:\n");
	  int i = vertaa(j1,j2);
	  printf("Vertailun tulos %d\n",i);
	
	  return 0;
	}
Ohjelman tulostus olisi seuraava:
	---------------------------------------------------
	Rakentaja: Osoitteet: olio FFF2, jono 06B2 Jono j1
	Rakentaja: Osoitteet: olio FFEE, jono 06BA Jono j2
	Menossa aliohjelmaan ftulosta:
	Aliohjelmassa ftulosta!
	Osoitteet: olio FFE8, jono 06B2 Jono j1
	Pois aliohjelmassa ftulosta!
	Hävittäjä: Osoitteet: olio FFE8, jono 06B2 Jono j1
	Menossa aliohjelmaan tulosta:
	Osoitteet: olio FFF2, jono 06B2 Jono <<<<
	Vertailu:
	Aliohjelmassa vertaa!
	Osoitteet: olio FFE4, jono 06B2 Jono <<<<
	Osoitteet: olio FFE8, jono 06BA Jono j2
	Hävittäjä: Osoitteet: olio FFE8, jono 06BA Jono j2
	Hävittäjä: Osoitteet: olio FFE4, jono 06B2 Jono <<<<
	Vertailun tulos 68
	Hävittäjä: Osoitteet: olio FFEE, jono 06BA Jono j2
	Hävittäjä: Osoitteet: olio FFF2, jono 06B2 Jono <<<<(c)<<2
	Null pojÂr assignment
Ongelma poistuu kun ystäväfunktioiden parametrit esitellään referensseiksi (const &j1...):
	---------------------------------------------------
	Rakentaja: Osoitteet: olio FFF2, jono 06B2 Jono j1
	Rakentaja: Osoitteet: olio FFEE, jono 06BA Jono j2
	Menossa aliohjelmaan ftulosta:
	Aliohjelmassa ftulosta!
	Osoitteet: olio FFF2, jono 06B2 Jono j1
	Pois aliohjelmassa ftulosta!
	Menossa aliohjelmaan tulosta:
	Osoitteet: olio FFF2, jono 06B2 Jono j1
	Vertailu:
	Aliohjelmassa vertaa!
	Osoitteet: olio FFF2, jono 06B2 Jono j1
	Osoitteet: olio FFEE, jono 06BA Jono j2
	Vertailun tulos -1
	Hävittäjä: Osoitteet: olio FFEE, jono 06BA Jono j2
	Hävittäjä: Osoitteet: olio FFF2, jono 06B2 Jono j1
Mikä oli ongelmana? Se selviää seuraavassa kappaleessa.


Prev Next Up Title Contents Index