Objektorientert programmering i C++
Formål
Klassedeklarasjon
- Beskrivelse av klassens grensesnitt
- Grensesnitt er deklarasjon av alle medlemmer i klassen
Klassedeklarasjon i C++
Innkapsling
- Lettere å forstå objektene
- Implementasjon kan endres uten å påvirke brukere av objekt
Innkapsling i C++
- Datamedlemmer (klassevariabler) skjules
- Tilgang til datamedlemmer gis gjennom metoder
- Tilgangsmetoder lages for attributter
Eksempel på innkapsling i C++
AnsiString hentNavn() const;
void settNavn( const AnsiString& navn );
Bruk av innkapslet attributt
AnsiString atle = “Atle”;
cout << medlem.hentNavn() << endl;
Implementasjon av metoder
- Er en “vanlig” funksjon som tilhører objekt/klasse
- Implementasjon plasseres i cpp-filer
- Deklarasjon plasseres i h-fil
- Filene har samme fornavn som klassenavnet
Implementasjon i C++
AnsiString Medlem::hentNavn() const {
void Medlem::settNavn( const AnsiString& navn ) {
Inline metode
- Metode som ikke blir oversatt til funksjonskall når den kalles
- Instruksjonene blir kopiert i stedenfor kall
- Metoder som implementeres i klassedeklarasjon blir inline
- Metoder med nøkkelordet inline foran blir inline (plassers i h-fil)
Konstruktør
- Kalles opp når et objekt av en objekttype (klasse) lages
- Er en metode i klassen
- Samme navn som klassen
- Har ikke returverdi
Deklarasjon av konstruktører
Medlem( const Medlem& medlem );
Implementasjon av konstruktør
Medlem::Medlem( const Medlem& medlem ) {
medlemsnr = medlem.medlemsnr;
medlemsnavn = medlem.medlemsnavn;
medlemsbet = medlem.medlemsbet;
Bruk av konstruktør i eks
Medlem medlem; // standard konstruktør kalles
AnsiString atle = “Atle”;
cout << medlem.hentNavn() << endl;
Destruktør
- Kalles opp når et objekt av en objekttype (klasse) ødelegges
- Er en metode i klassen
- Samme navn som klassen med tilde foran
- Har ikke returverdi
- Kun en destruktør i en klasse
Deklarasjon av destruktør
Medlem( const Medlem& medlem );
Implementasjon av destruktør
Bruk av destruktør
Medlem medlem; // standard konstruktør kalles
AnsiString atle = “Atle”;
cout << medlem.hentNavn() << endl;
} // her kalles destruktøren opp
Fullstendig klasse Medlem
Medlem( const Medlem& medlem );
void settNavn( const AnsiString& navn );
AnsiString hentNavn() const;
void settBetalt( bool betalt );
bool erLik( const Medlem& medlem ) const;
bool erLik( const Medlem& medlem ) const;
Medlem::Medlem() {
Medlem::Medlem( const Medlem& medlem ) {
medlemsnr = medlem.medlemsnr;
medlemsnavn = medlem.medlemsnavn;
medlemsbet = medlem.medlemsbet;
Medlem::~Medlem() {
void Medlem::settNr( long nr ) {
long Medlem::hentNr() const {
void Medlem::settNavn( const AnsiString& navn ) {
void Medlem::settNavn( const AnsiString& navn ) {
AnsiString hentNavn() const {
void Medlem::settBetalt( bool betalt ) {
void Medlem::settBetalt( bool betalt ) {
bool Medlem::erBetalt() const {
bool Medlem::erLik( const Medlem& medlem ) const {
return medlemsnr == medlem.medlemsnr;
void Medlem::skriv() const {
void Medlem::skriv() const {
cout << medlemsnr << medlemsnavn << endl;
cin >> medlemsnr >> medlemsnavn >> medlemsbet;
Dynamiske objekt
- Vi må sørge for opprettelse og ødelegging av objektene
- Behandles via pekere til objektene
Dynamisk lagd objekt
Medlem* medlem = new Medlem;
AnsiString atle = “Atle”;
medlem->settNavn( atle );
Eksempel - arkiv
void settInn( Medlem* medlem );
void endre( Medlem* medlem );
bool erMedlem( Medlem* medlem );
PPT Slide
int finn( Medlem* medlem );
Arkiv::Arkiv() {
for( int i = 0; i < antall; i++ )
void Arkiv::settInn( Medlem* medlem ) {
void Arkiv::settInn( Medlem* medlem ) {
cerr << “Ikke plass til medlem” << endl;
void Arkiv::endre( Medlem* medlem ) {
void Arkiv::endre( Medlem* medlem ) {
cerr << “Medlem er ikke i arkiv” << endl;
bool Arkiv::erMedlem( medlem* medlem ) {
bool Arkiv::erMedlem( medlem* medlem ) {
return finn( medlem ) > 0;
cout << “Medlemmer: nr og navn” << endl;
for( int i = 0; i < antall; i++ )
int Arkiv::finn( Medlem* medlem ) {
int Arkiv::finn( Medlem* medlem ) {
for( int nr = 0; nr < antall && !funnet; nr++ )
funnet = arkiv[nr]->erLik( *medlem );
Bruk av Arkiv
cout << “1 - nytt medlem” << endl;
cout << “2 - endre medlem” << endl;
cout << “3 - vis medlemmer” << endl;
cout << “4 - søk medlem” << endl;
cout << “5 - avslutt” << endl;
char lesValg() {
} while( svar < ‘1’ || svar > ‘5’ );
void main() {
switch( lesValg() ) {
cout << “Oppgi nr og navn:”;
case ‘2’:
cout << “Oppgi nr og navn:”;
case ‘4’:
cout << “Oppgi nr og navn:”;
if( dphil.erMedlem( medlem )
cout << “Er medlem “ << endl;
cout << “Er ikke medlem” << endl;
case ‘5’:
Sortert arkiv
- Metodene innsett og finn endres
- finn behøver ikke endres, men kan forenkles
void Arkiv::settInn( Medlem* medlem ) {
void Arkiv::settInn( Medlem* medlem ) {
while( i<antall && arkiv[i]->erMindre(*medlem) )
for( int j = antall; j > i; j-- )
cerr << “Ikke plass til medlem” << endl;
bool Medlem::erMindre( const Medlem& medlem ) const {
bool Medlem::erMindre( const Medlem& medlem ) const {
return medlemsnr < medlem.medlemsnr;
Oppgaver
- Endre Arkiv slik at den blir sortert
- Legg til fjern-metode til Arkiv-klassen
- Oppgaver fra kap 11 i boken
- 11.2, 11.4, 11.5, 11.1, 11.3
Løsningsforslag til 11.2
int main( int argc, char **argv ) {
Sirkel sirkel( Punkt(4, 4), 4 );
sirkel.settSentrum( 5, 6 );
class Sirkel {
Sirkel( const Sirkel& s );
Sirkel( const Punkt& p, int r );
Punkt hentSentrum() const;
void settSentrum( const Punkt& p );
void settSentrum( int nyX, int nyY );
void settRadius( int r );
private:
Sirkel::Sirkel( const Sirkel& s ) {
Sirkel::Sirkel( const Sirkel& s ) {
Sirkel::Sirkel( const Punkt& p, int r ) {
void Sirkel::visData() {
cout << "Sentrum: " << sentrum.hentX() << ", " << sentrum.hentY() << endl;
cout << "Omkrets: " << 2*3.14*radius << endl;
cout << "Areal : " << 3.14*radius*radius << endl;
Punkt Sirkel::hentSentrum() const {
void Sirkel::settSentrum( const Punkt& p ) {
void Sirkel::settSentrum( const Punkt& p ) {
void Sirkel::settSentrum( int nyX, int nyY ) {
int Sirkel::hentRadius() const {
int Sirkel::hentRadius() const {
void Sirkel::settRadius( int r ) {
class Punkt {
private:
Punkt::Punkt( const Punkt& p ) {
Punkt::Punkt( const Punkt& p ) {
Punkt::Punkt( int x0, int y0 ) {
void Punkt::settX( int nyX ) {
void Punkt::settX( int nyX ) {
int Punkt::hentX() const {
void Punkt::settY( int nyY ) {
void Punkt::settY( int nyY ) {
int Punkt::hentY() const {
Løsningsforslag 11.1
int main( int argc, char **argv ) {
cout << "Skriv 5 tall: ";
cout << "Sum: " << t.sum() << " Gj.snitt: ”;
cout << t.gjennomsnitt() << endl;
cout << t.sum() << " " << t.gjennomsnitt();
static const int MAX = 5;
static const int MAX = 5;
void endre( int i, int v );
Tab::Tab() {
for( int i = 0; i < MAX; i++ )
void Tab::registrering() {
for( int i = 0; i < MAX; i++ )
int Tab::sum() {
for( int i = 0; i < MAX; i++ )
double Tab::gjennomsnitt() {
double Tab::gjennomsnitt() {
return (double)sum()/MAX;
void Tab::endre( int i, int v ) {