Muß es ein Zeiger sein?
Sind andere Namen für ein Objekt (Englisch: Alias)
Erlauben indirekte Verarbeitung von Objekten (wie Zeiger)
Brauchen keine umständliche
Zeiger Syntax
Referenzen müssen initialisiert werden
Aber nicht mit Adressen, sondern mit den Objekten selbst
Referenzen können nicht geändert
werden!
int intval = 4096;
int &refval = intval; //ok int &refval1; //falsch
refval++; //inkrementiert intval
int intval = 4096;
int &refval = intval;
int newval = 1024;
refval = newval; //d.h. intval = 1024;
Jeder Referenzerklärung muss ein
" & " vorausgehen
Eine const Referenz eines Typs kann mit einem anderen
Variablentyp oder Konstante initialisiert werden
float x = 3.14159;
const int &intref = x;
Zur Laufzeit wird der Referenz- parameter dem aktuellen
Parameter zugeordnet (Binding) Folge: Es wird mit dem originalen Objekt gearbeitet, nicht mit einer Kopie
In den Funktionen wird mit der
Referenzvariablen gearbeitet, nicht
mit der Adresse
void tausch(int &x, int
&y) {
int temp;
temp = x;
x = y;
y = temp;
} ...
int Tab[5] = {1,2,3,4,5};
tausch(Tab[3],Tab[0]);
Effekt:
x = Tab[3]; y = Tab[0];<KlassenNamen>(const <KlassenNamen> &<KlassenObjekt>)
{ ... }
#ifndef _Reihung
#define _Reihung
#include <iostream>
class Reihung{
private:
int *p;
int groesse;
public:
Reihung(int);
Reihung(const Reihung &);
int ElementHolen(int i){return p[i];}
void ElementSetzen(int i, int x){
if(i >= 0 && i < groesse) p[i] = x;}
};
#include <stdlib.h>
Reihung::Reihung(int gr) {
p = new int[gr];
if (!p) exit(0);
groesse = gr;
cout << "Konstruktor hier aufgerufen" << endl;
}
Reihung::Reihung(const Reihung &a) {
p = new int[a.groesse]; //privater Zugriff if (!p) ...
for (int i = 0; i < a.groesse; i++) p[i] = a.p[i];
cout << "Kopierkonstruktor hier aufgerufen" << endl;
!
int main(void){
Reihung Tab(10);
for (int i = 0; i < 10; i++) Tab.ElementSetzen(i,i);
for (int i = 9; i >= 0; i--) cout << Tab.ElementHolen(i);
cout << endl;
Reihung Kopie = Tab;
for (int i = 0; i < 10; i++) cout << Kopie.ElementHolen(i);
cout << endl;
return 0;
}
Man achte auf inline Konstruktoren Datendeklaration überall in C++
In C++ nicht
malloc, sondern
newnew
mit
[]allokiert eine Reihung von Objekten
Parameter bei Kopierkonstruktor
ist const -- siehe unten
new
new wird verwendet, um Speicher vom Heap zu holen. Beispiel:
int *p; p = new int;
Unterschiede zu
malloc()Die Makro
sizeof(int)ist nicht zu verwenden
Zeiger cast vom
void *fehlt auch
new
und
malloc()nicht mischen!
"
Sind dafür verantwortlich, Objekt- komponenten zu bereinigen, wenn diese nicht mehr aktiv im
Programm sind
Wie Konstruktoren, gibt es immer einen Default-Destruktor
Syntax: ~<KlassenName>();
~Reihung(){delete[] p;}
Destruktoren werden i. d. Regel geschrieben, wenn new bei
Konstruktor oder Element- funktionen verwendet wurde Hier: Destruktor räumt
Speicherplatz für die Reihung ab.
# $
Genau wie Variablen durch const von Änderung geschützt werden, kann man Objekte mit const schützen
Um zu gewährleisten, dass
Elementfunktionen Klassenfelder
konstanter Objekte nicht ändern, werden diese auch als const definiert
Elementfunktionsnamen können mit
const überladen werden
class meineKlasse{
private:
int x;
public:
void setX(const int);
int getX();
int getX() const; //fuer const-Objekte };
void meineKlasse::setX(const int num) { x = num;}
int meineKlasse::getX() {
cout << "Normale Elementfunktion" << endl;
return x;
}
int meineKlasse::getX() const {
cout << "Konstante Elementfunktion" << endl;
return x;
!
int main(void) {
const meineKlasse Objekt1(5);
meineKlasse Objekt2;
Objekte2.setX(3);
cout << Objekte1.getX() << endl;
cout << Objekte2.getX() << endl;
return 0;
}
Ergebnis:
Konstante Elementfunktion 5
Normale Elementfunktion