Tehtävä:
Kurssin viimeisessä tehtävässä sinun tulee määritellä luokka Luku, sekä toteuttaa tähän kuuluvat jäsenfunktiot. Luokka sisältää yhden jäsenmuuttujan luku_, joka on osoitin kokonaislukutyypin (int) tietoon. Kun luokasta muodostetaan olio, on sen oletusmuodostimen varattava osoittimen mukainen muistialue, osoitettava varattu muisti luokan jäsenmuuttujaan ja alustettava varattu tila arvolla 0. Vastaavasti purkajan tehtävänä on vapauttaa luokan tarvitsema muisti kun luku-olio tuhotaan.
Luku-luokassa on kaksi tavallista jäsenfunktiota: Tulosta() ja Muuta(). Edellinen funktio tulostaa luku-olion jäsenmuuttujan osoittaman sisällön esimerkkitulosteen mukaisesti ja jälkimmäinen muuttaa sisällön parametrina välitetyllä arvolla. Tulosta ei siis ota vastaan parametreja eikä palauta arvoa, kun taas Muuta saa kokonaislukuparametrin muttei palauta mitään.
Edellisten lisäksi luokkaan on kirjoitettava kopiointi- ja sijoitusmuodostimet. Kopiomuodostimen on toimittava siten, että luku-olion kopion jäsenmuuttujan viittaama arvo on sama kuin alkuperäisellä luku-oliolla kuitenkin niin, että alkuperäinen ja kopio viittaavat eri muistialueisiin. Muistialueet sisältävät vain saman arvon. Sijoitusoperaattorin toteuttamisessa on toimittava samoin. Jos luku-olio sijoitetaan toiseen, saa sijoituksen kohde sijoitettavan luku-olion tilan mutta muutokset sijoituksen kohteena olevan olion tilassa eivät saa näkyä sijoitettavassa oliossa.
Luokkaa testataan pääohjelmassa, josta siitä tehdään luku-olioita joita kopioidaan ja sijoitetaan toisiinsa.
Example output:
Luku on: 100
Luku on: 100
Luku on: 100
Luku on: 200
Luku on: 300
Luku on: 200
Vastaus:
#include <iostream>
using namespace std;
class Luku {
public:
Luku();
~Luku();
void Tulosta();
void Muuta(int luku);
// Introduce copy constructor
Luku(const Luku& obj);
// Introduce assignment operator
Luku& operator=(const Luku& obj);
private:
int * luku_;
};
Luku::Luku()
{
luku_ = new int;
*luku_ = 0;
}
Luku::~Luku()
{
delete luku_;
}
void Luku::Muuta(int luku)
{
*luku_ = luku;
}
void Luku::Tulosta()
{
cout << "Luku on: " << *luku_ << endl;
}
// Define copy constructor: perform deep copy
Luku::Luku(const Luku& obj)
{
luku_ = new int;
*luku_ = *obj.luku_;
}
// Define assignment operator
Luku& Luku::operator=(const Luku& obj)
{
*luku_ = *obj.luku_;
return *this;
}
//** Pre-defined code in the assignment **//
int main()
{
Luku eka;
eka.Muuta(100);
eka.Tulosta(); // Luku on: 100 Print current value of eka
Luku toka(eka);
toka.Tulosta(); // Luku on: 100 copy of eka
eka.Muuta(200);
toka.Tulosta(); // Luku on: 100 copy of original eka, different memory address
toka = eka;
toka.Tulosta(); // Luku on: 200; toka gets same value than eka
eka.Muuta(300);
eka.Tulosta(); // Luku on: 300 // print current value of eka
toka.Tulosta(); // Luku on: 200 // print current value of toka
return 0;
}
//** ---------- ---------- ---------- **//