Modulaarinen ohjelmointi, jossa funktiot ja esitys ovat samassa loogisessa kokonaisuudessa. Esim. luokat, rajapinnat.
Huom: Abstrahoinnista seuraa, että esitys on riippuvainen luokasta (tosin yksityisesti).
Olio-ohjelmointi
Päätä, millaisia luokkia tarvitset; määrittele kattavat operaatiot jokaista luokkaa varten; tee yhteisistä ominaisuuksista eksplisiittisiä periytymisen avulla.
Tiedon abstrahointi + yhteisten ominaisuuksien etsiminen. Esim. luokkahierarkiat.
Geneerinen ohjelmointi
Päätä tarvittavat algoritmit; parametroi ne siten, että ne toimivat monenlaisten sopivien tyyppien ja tietorakenteiden kanssa.
Templatet.
Operaattorien kuormittaminen [11]
Yleistä:
binäärinen operaattori on joko (ei-staattinen) metodi, jolla 1 argumentti tai funktiona, jolla 2 argumenttia.
unaarinen operaattori on joko metodi, jolla ei ole argumentteja tai funktio, jolla 1 argumentti.
etuliite: C.operator@() tai operator@(a).
jälkiliite: C.operator@(int) tai operator@(a,int).
kuormitetut =, [], () ja -> ovat aina ei-staattisia metodeita (jotta 1. operandi olisi v-arvo).
=, & ja , -operaattoreilla on määritelty merkitys olioilla, joka voidaan välttää piilottamalla ne.
Huom: myös enum-tyypeille voi määritellä operaattorit.
Muunnosoperaattoreilla (esim C::operator int() const { return c; }) voidaan tehdä implisiittinen tyypinmuunnos käyttäjän määrittelemästä luokasta sisäiseen tyyppiin.
Useista eri tyypeistä koostuvista operaattorien arvoista (seka-aritmetiikka) seuraava funktioiden määrän kasvu voidaan välttää korvaamalla kaikki yhdellä funktiolla ja argumenteille tarvittavat muunnosoperaattorit. (esim. luokka Complex ja argumenttityypit double, Complex)
explicit -avainsanalla vaaditaan, että funktion argumentti on eksplisiittisesti annettua tyyppiä.
()-operaattoria voidaan käyttää esim. määriteltäessä funktionkaltaisia olioita, osamerkkijonon haussa tai moniulotteisen taulukon indeksoinnissa fortran-tyyliin. (argumentteja voi useampia)
Sijoitusoperaattori ja copy-konstruktori eivät periydy.
Viitteistä:
Copy-konstruktorissa viitearvo on välttämätön. Jos viitearvoa ei olisi, kutsu johtaisi loputtomaan rekursioon.
Viittaukset ovat välttämättömiä käytettäessä operaattoriaritmetiikkaa suurilla luokilla. Osoittimet eivät käy, koska osoittimeen kohdistuvaa operaattoria ei voi määritellä uudelleen.
Operaattorista voidaan palauttaa 'turvallisesti' viitearvoinen olio käyttämällä operaattorin puolella apufunktiona staattista oliotaulukkoa, jossa 'kierrätetään' sijoitettavaa oliota. Viite palautetaan taulukosta.
Metodeista ja ystävistä:
Funktio pääsee käsittelemään luokan private-osaa.
Funktio on luokan viittausalueella.
Funktiolla on this-osoitin.
Metodit
X
X
X
Staattiset metodit
X
X
Ystävät
X
Luokka voidaan julistaa toisen luokan ystäväksi luokan sisäisellä määrittelyllä friend class C.
Huom: ystävän esittely ei tuo nimeä ympäröivälle viittausalueelle. Ystäväluokkien/funktioiden täytyy olla esiteltynä välittömästi ystävän esittelyn viittausalueen ympärille (tai ystäväfunktiolla täytyy olla luokkaansa kuuluva argumentti, jolloin se voi olla muuallakin).
Kaksioperandiset operaattorit (esim. +) ovat yleinen syy käyttää ystäväfunktioita, kun operaattorin argumenteissa on odotettavissa implisiittisiä tyyppimuunnoksia.
Apufunktiot kannattaa liittää luokkiin nimiavaruuksilla.
Osoittimista:
-> -operaattorilla voidaan luoda 'älykkäitä osoittimia' (esim. iteraattorit). T* operator->() { ... return &t; }
Jos määritellään ++- ja -- -operaattorit osoittimien selaamista varten, ne kannattaa määritellä sekä etu- että jälkiliittenä.
Esimerkki: merkkijonoluokka.
Käytetty apuluokkaa esityksen erottamiseen käytöstä. Apuluokassa on reference count, joka mahdollistaa nopean sisällön kopioimisen (copy-konstruktorit ja sijoitukset)
Määritelty erikseen metodit tarkistettuun ja tarkistamattomaan, nopeaan lukemiseen ja asettamiseen.
[]-operaattorissa on vältetty saantiarvon muuttaminen määrittelemällä erikseen const-operaattori ja käyttämällä muuten apuluokkaa viittaamaan merkkijonoon (kopioidaan vain tarvittaessa), jonka kautta arvoja päästään muuttamaan.
Aliluokat [12]
Viipalointi
konkreettinen luokka yrittää tehdä kopiota itsestään yliluokan metodilla, mutta yliluokka ei tiedä perityissä luokissa olevista attribuuteista (jos olio on todellisuudessa alaluokkaa). Voidaan välttää käyttämällä osoittimia ja referenssejä, jotka kutsuvat virtuaalista kopiointifunktiota.
Keinoja selvittää, mihin luokkaan yliluokan tyyppia oleva osoitin kuuluu:
Varmistetaan, että osoitin viittaa vain yhdentyyppisiin olioihin
Käytetään tyyppikenttää. (Vaarallinen ratkaisu suuriksi kasvavissa ohjelmissa, erityisesti, jos hierarkiaan lisätään uusia luokkia jälkeenpäin. Tarvitaan ulkoisia käsittelyfunktioita ja kasvavia switch-lauseita.)
Käytetään tyyppimuunnosta dynamic_cast. Oma rekursiivinen puun läpikäyntiehdotukseni perustuu tähän ja funktio-osoittimiin.
Käytetään virtuaalifunktioita. (Ihanteellinen tapaus, erityisesti yhdistettynä abstrakteihin rajapintoihin)
Esiverkki: Ival_box -luokkahierarkia
Tehdään abstakti Ival_box, josta peritään edelleen abstrakteja erikoistuneempia muotoja Ival_slider ym.
Boxin käyttämiseen erilaisissa järjestelmissä on olemassa Window- ja esim. slider- luokat, jotka sisältävät mm. piirtofunktiot kyseistä järjestelmää varten.
Moniperitään abstrakti erikoistuma Boxista ja protected-tyylillä järjestelmäriippuvaiset funktiot, tehdään konkreetti luokka.
Luokan käyttäjien ei tarvitse ottaa kantaa käyttöliittymään, mutta uudet luokat voivat käyttää sitä (johtuen protected-perinnästä.
Uusien luokkien luomista selkeyttämään voitaisiin tehdä jokaiseen eri järjestelmään liittyvä Factory-luokka (jotka on peritty yhteisestä Factory-rajapinnasta), johon on koottu kaikkien tiettyyn järjestelmään liittyvien käyttöliittymäluokkien generointi. ('virtuaalikonstruktori'). Näin käyttäjä voi luoda käyttöliittymäluokkia Factoryn avulla tarvitsematta tietää, minkä järjestelmän luokista oikeastaan on kysymys.