Mittels #define lassen sich Textersetzungen realisieren. So könnte man zB eine 'Funktion' max schreiben um den größeren von 2 Werte zu 'returnen':
#define max(a, b) ( (a)>(b) ? (a) : (b) )
Dies hat aber eine Menge Nachteile, denn der Präprozessor ignoriert Sichtbarkeitsbereiche und führt die Ersetzung immer durch:
class Array
{
private:
int val[10];
public:
//...
int max() const
{
int m=val[0];
for(int i=1; i<10; ++i)
{
if(val[i]>m) m=val[i];
}
return m;
}
};
Dies wird einen Fehler produzieren. Weiters wird jedes Element von max() mehrmals ausgewertet: max(++a, ++b); Entweder a oder b wird doppelt ausgewertet - also 2 mal inkrementiert. Deshalb haben wir bei max auf die Klammern gesetzt: damit der Ausdruck a immer als a ausgewertet wird und nicht die Operatorenreihenfolge eine Rolle spielt:
#define mul(a, b) a*b
mul(1+2, 3+4);
//ergibt: 1+2*3+4 und das ist: 1+(2*3)+4
Aber #define ist nicht nur schlecht, es hat auch gute Seiten. zB um wirklich Textersetzungen vorzunehmen:
#define NoCopyAble(Class) Class(Class const&); Class& operator=(Class const&);
class Foo
{
private:
NoCopyAble(Foo);
public:
//...
};
Und schon ist Foo nicht kopierbar, da wir den operator= und den Kopierkonstruktor private deklariert haben.
Es gibt 2 wichtige definierte Konstanten: __FILE__ und __LINE__. __FILE__ gibt die aktuelle Datei an und __LINE__ die aktuelle Zeile:
#include <iostream>
using namespace std;
int main()
{
cout<<"Dieser Text steht in der Datei "<<__FILE__<<" in der "<<__LINE__<<". Zeile\n";
}