In C++11 sind einige Mechanismen dazu gekommen, um die Verwaltung von dynamisch angelegtem Speicher zu vereinfachen.
Bereits in früheren C++ Versionen war std::auto_ptr zu finden. Der Auto-Pointer std::auto_ptr wird allerdings in C++11 als veraltet (deprecated) markiert.
Als Ersatz wird std::unique_ptr für std::auto_ptr angeboten, sowie std::shared_ptr als Alternative zu std::auto_ptr.
Desweiteren gibt es std::weak_ptr und einige mehr.

Die nachfolgende Klasse soll für weitere Beispiele genügen:

class Foo
{
    public: Foo() : nr(0) { std::cout<<"foo created\n"; }
    public: ~Foo() { std::cout<<"foo deleted\n"; }

    public: int nr;
};

std::shared_ptr (die Grundlagen)

std::shared_ptr repräsentiert den Referenzzähler eines Objektes, sodass jede std::shared_ptr Kopie auf das selbe Objekt verweist.
Deshalb sollte die Verwendung des std::shared_ptr immer mit bedacht gehandhabt werden, um zirkulierende Referenzen (Referenzen zweier Objekte auf einander) zu vermeiden.
Wie dies zu verhindern ist folgt später.

Der Konstruktor des std::shared_ptr Containers hat diverse Überladungen. Interessant für dieses Tutorial sind lediglich folgende:

constexpr shared_ptr();
template<class Y> explicit shared_ptr(Y* ptr);
template<class Y, class Deleter> shared_ptr(Y* ptr, Deleter d);

Ein leerer Zeiger kann also wie foglt angelegt werden:

std::shared_ptr<Foo> f1;

Ein Zeiger auf ein neues Objekt der Klasse Foo wird folgendermaßen angelegt:

std::shared_ptr<Foo> f2(new Foo);

Um f1 nun ebenso auf f2 zeigen zu lassen kann man die gewohnte Syntax nutzen:

f1 = f2

Mit der Methode reset() kann ein std::shared_ptr wieder auf nichts zeigen.
Mit der Methode use_count() kann die Anzahl der Referenzen ausgegeben werden.

    std::shared_ptr<Foo> f1;
    std::shared_ptr<Foo> f2(new Foo);

    f1 = f2; // Beide besitzen den Speicher

    std::cout<<"Referenzen: "<<f1.use_count()<<std::endl;
    f2.reset(); // Referenz wird entfernt, der reservierte Speicher ist allerdings noch vorhanden!

    std::cout<<"Referenzen: "<<f1.use_count()<<std::endl;
    f1.reset(); // Erst jetzt wird auch der Speicher gelöscht
// Ausgabe: foo created
// Referenzen: 2
// Referenzen: 1
// foo deleted 

std::weak_ptr

Um das Problem der circular references zu umgehen, kann ein schwacher Zeiger verwendet werden.
Er besitzt dabei nicht den Speicher, sondern zeigt lediglich auf diesen. Wird das Besitzerobjekt gelöscht, so zeigt std::weak_ptr ins nichts.
Mit der Methode lock() des std::weak_ptr wird ein std::shared_ptr angelegt, welcher dann verwendet werden kann.

Auf den Inhalt eines Pointers kann wie gewohnt mit dem (überladenen) * Operator zugegriffen werden (resp. auch ->)

    std::weak_ptr<Foo> f1;
    std::shared_ptr<Foo> f2(new Foo);

    f1 = f2; // Nur f2 besitzt den Speicher
    f2->nr = 3; // Nummer setzen
    if(auto ptr = f1.lock()) // ptr und f2 besitzen nun den Speicher
    {
        std::cout<<"Die Nummer: "<<ptr->nr<<std::endl;
    } // ptr ist nicht mehr Besitzer

    f2.reset(); // Referenz entfernen (der Speicher wird freigegeben, da f2 der einzige Besitzer ist

    if(auto ptr = f1.lock()) // Kein Speicher mehr vorhanden, es wird immer der else-Zweig aufgerufen
    {
        std::cout<<"Die Nummer: "<<ptr->nr<<std::endl;
    }
    else
    {
        std::cout<<"Foo existiert nicht mehr!"<<std::endl;
    }
// Ausgabe:
// foo created
// Die Nummer: 3
// foo deleted
// Foo existiert nicht mehr!

std::unique_ptr

Er verhält sich ähnliche wie ein std::shared_ptr, mit dem Unterschied, dass er immer der alleinige Besitzer ist.
Es verwaltet immer ein einziges Objekt, eine weietre Referenz auf dieses Objekt ist nicht möglich.
Der Besitz kann durch std::move(T) verschoben werden:

std::unique_ptr p1(new Foo); // p1 ist der Besitzer
std::unique_ptr p2(std::move(p1)); // p2 ist der Besitzer

Fazit

In C++11 ist das Nutzen von Zeigern erheblich vereinfacht worden.
Die Verwendung der neuen Mechanismen dürfte den ein oder anderen Fehler verhindern.
Allerdings sollte man keinesfalls ohne Sinn und Verstand nun Pointer nutzen, besonders,
da durch die fehlerhafte Nutzung von std::shared_ptr ein Objekt im Speicher gehalten werden kann.
Ab und an bieten sich die „klassischen“ Referenzen eher an, als ein shared_ptr, weak_ptr oder unique_ptr.

Was sind konstante Ausdrücke?

Wie bei der Template Metaprogrammierung, sollen bei konstanten Ausdrücken Werte zur Compile-Zeit berechnet werden.
Der Sinn des Ganzen ist es, feststehende Werte (Konstanten) nicht zur Berechnung auf die Laufzeit zu schieben, denn ihr Wert ändert sich nie.
Ein einfaches Beispiel wäre power(16, 2).
Dieser Funktionsaufruf wird immer 256 liefern, egal wann er mit diesen Parametern im Programm aufgerufen wird.
Bis vorkurzem ging das in C++ nur mit – für ungeübte Programmierer – unübersichtlichen Templates.
Mit C++11 wird nun das Keyword constexpr eingeführt – analog zu dem älteren const für feste Werte.

Die Syntax bei constexpr ist die übliche von C++, was das Ganze besonders einfacher zu lesen macht.
Konstante Ausdrucks-Metaprogrammierung (constexpr meta-programming) wird in C++11 deswegen wahrscheinlich das Mittel der Wahl für Metaprogrammierung sein.

Potenzierung per rekursiven Verfahren

Vor C++11 musste dies per TMP implementiert werden, dies möchte ich hier nicht näher erläutern, aber zum Vergleich trotzdem einmal den Quelltext zeigen,
damit nachher ein besserer Vergleich und Eindruck von und zwischen CMP und TMP entsteht.

template<int tmp_Basis, unsigned int tmp_Exponent>
struct tmp_Power
{
    enum
    {
        tmp_result = tmp_Basis * tmp_Power<tmp_Basis, tmp_Exponent-1>::tmp_result
    };
};

template<int tmp_Basis>
struct tmp_Power<tmp_Basis, 0>
{
    enum
    {
        tmp_result = 1
    };
};

Ein Aufruf für die Potenzierung von 16^2 sähe wie folgt aus: tmp_Power::tmp_result.
Dies entspricht nicht der gewohnten C++ Syntax und wird bei größeren Berechnungen auch mal schnell unübersichtlich, wenn die Dokumentation nicht stimmt.
Ein weiteres Problem ist, dass der Datentyp double (sowie float) in der TMP nicht zur Verfügung steht.
Ein Aufruf wie tmp_Power ginge somit nicht.

Das selbe Verfahren mit der CMP sieht um Längen verständlicher aus und könnte (bis auf das Keyword constexpr) auch C++03 Code sein:

constexpr double power(double basis, unsigned int exponent)
{
  return !exponent ? 1 : basis * power(basis, exponent-1);
}

Diese Funktion wirkt wie jede andere in C++ auch, ist aber ein konstanter Ausdruck. Konstante Werte werden also nicht erst zur Laufzeit berechnet.
Im Unterschied zur TMP kann man CMP aber auch mit Laufzeitwerten füttern, dann wird allerdings erst die Berechnung des Wertes zur Laufzeit durchgeführt.

Der folgende Aufruf gibt 72.25 aus:

printf("power(8.5, 2) = %f\n\n", power(8.5, 2));

Zur Laufzeit wird nurnoch printf(…, 72.25); übergeben ansteller längeren rekursiven Berechnung.
Hier einmal der Vergleich:

static_assert(power(8.5, 2), "...power"); // Compile-Zeit
double a = 8.5;
power(a, 2); // Laufzeit

Auswirkungen auf die Compile-Zeit

Wer TMP nutzt weiß, dass viele Rekursionen (5000+) erhebliche Zeit in Anspruch nehmen.
Doch CMP mit großer Tiefe (z.B. das Generieren von Primzahlen) benötigt nur ein Bruchteil der Zeit.
CMP wurde extra für die Metaprogrammierung entworfen, während TMP eher „entdeckt“ wurde.
Daher sind viele Optimierungsprozesse für CMP von Anfang an vorhanden, während bei der TMP z.B. oft Analysen mehrfach durchgeführt werden, da der eine Aufruf vom Anderen nichts weiß.

Alles in Allem wird die konstante Ausdrucks-Metaprogrammierung die Metaprogrammierung in C++ erheblich voran treiben, da auch weniger Metaprogrammierung versierte Programmierer diesen Mechanismus nutzen können.

Was ist Template Metaprogramming?

Bei der Template Metaprogramming handelt es sich um eine generische Programmiertechnik, die bereits zur Compile-Zeit durchgeführt wird.
D.h. bereits in den ersten Phasen wird dieser Code verarbeitet und steht zur weiteren Verarbeitung bereit.
Daraus folgt allerdings auch, dass die Template Metaprogramming nur mit Daten funktioniert, die auch schon zur Compile-Zeit zur Verfügung stehen.

Arten der Template Metaprogramming:

Generell lässt sich sagen, dass es zwei Unterarten der Metaprogrammierung gibt.
Da wäre einmal die, welche Quellcode (also Instructions, die zur Laufzeit verarbeitet werden) erzeugt (TMP code generator)
sowie jene, welche lediglich einen Wert berechnet und keine Instructions für die Laufzeit erzeugt (TMP calculator).

TMP calculator

Zu erst muss gesagt werden, dass bei der Template Metaprogramming in einem funktionalen Paradigma programmiert wird und es deshalb z.B. keine Schleifen gibt.

Als erstes schauen wir uns deshalb ein Programm an, welches die Fakultät zur Laufzeit berechnet.

int fac(int n)
{
    return n != 1 ? fac(n-1) * n : 1;
}

Mit Festwerten wie fac(0), fac(1), fac(10) etc. pp. wäre das eine Verschwendung der Laufzeit.
Und genau hier kommt die Template Metaprogramming zum Tragen!

Dazu erst einmal der Quelltext:

template<int N>
class tmp_Fac
{
    public:
        enum { tmp_result = N * tmp_Fac<N - 1>::tmp_result };
};

class tmp_Fac<1>
{
    public:
	enum { tmp_result = 1; }
};

Auch bei dieser Lösung wird rekursiv gearbeitet. Werte müssen als Konstanten abgespeichert werden (z.B. als enum Wert).
Mit class tmp_Fac erreichen wir, dass wenn int N = 1 ist, diese Klasse aufgerufen wird und nicht jene, die für alle Werte gilt.

Das Ergebnis im Assembler könnte z.B. wie folgt lauten: mov eax, 720
für den Aufruf:

tmp_Fac<6>::tmp_result

TMP code generator

Funktionsaufrufe erzeugen in der Template Metaprogramming Instructions, ebenso ihr Inhalt.
So möchten wir, dass die Berechnungskette für tmp_Fac dargestellt wird:

template<int N>
class tmp_PrintFac
{
    public:
        static inline void tmp_exec()
        {
            std::cout << N << " * ";

            tmp_PrintFac<N - 1>::tmp_exec();

            std::cout << " ";
        }
};

class tmp_PrintFac<1>
{
    public:
        static inline void tmp_exec()
	{
            std::cout << "1";
	}
};

Dieser Code erzeugt bei tmp_PrintFac::tmp_exec() folgende Aussage: „3 * 2 * 1“.
(Dabei werden N * 2 – 1 häufige std::cout Aufrufe getätigt!)

Im nächsten Artikel werde ich erklären, wie man mithilfe der Template Metaprogramming Bedingungen erstellt und welche Tücken dieses System verbirgt.

Was ist ein Zeiger?

Ein Zeiger ist ein Wert, der die Speicheradresse eines anderen Wertes enthält.
Durch die Nutzung von Zeigern kann unter Umständen das Kopieren von Datensätzen erspart werden, desweiteren sind sie ein wichtiger Bestandteil um dynamischen Speicher zu verwalten.

Folgendes Bild zeigt eine Variable x und einen Zeiger y der auf x zeigt

Dabei ist der Inhalt von y (2) die Adresse von x.

Definition eines Zeigers in C++

Um bei der Definition einen Zeiger kenntlich zu machen, wird das Sternchen verwendet:

int *zeiger;

Dabei ist der Typ des Zeigers (hier int) für die Zeigerarithmetik von Bedeutung.
Der Zeiger sollte also den selben Typen haben, wie die Variable, auf die er zeigt.

Zuweisung einer Variable

Um einem Zeiger eine Variable zu zuwiesen, wird die Adresse der Variable benötigt.
Dies geschieht mit dem Adressoperator & (Kaufmanns-Und).

int zahl = 19;
int *zeiger = &zahl;

Eine Zuweisung muss allerdings nicht nur bei der Initialisierung erfolgen, sondern kann auch an anderer Stelle im Quelltext folgen.

zeiger = &zahl;

Hier bei muss das Sternchen vor dem Zeiger entfallen, denn an der Speicherstelle der Zeigervariable zeiger soll die Adresse von zahl geschrieben werden.
(Also markiert das Sternchen nur bei der Deklaration und Initialisierung, dass es sich um einen Zeiger handelt)

Zugriff per Zeiger

Um an den Inhalt der Variable zu kommen, auf die gezeigt wird, muss das Sternchen vor dem Zeigernamen stehen.
*zeiger ist also der Inhalt der Adresse auf die zeiger zeigt.

Somit gibt Folgendes 19 aus:

std::cout << *zeiger << std::endl;

Desweiteren kann auch über den Zeiger auf zahl geschrieben werden:

*zeiger = 20;
std::cout<< *zeiger << std::endl << zahl << std::endl; // gibt beides jeweils 20 aus

Anmerkung: Bei dem Werteoperator des Zeigers handelt es sich nicht um die mathematische Multiplikation!
Der Werteoperator steht über dem Multiplikationsoperator somit ergibt dieses Beispiel keine Probleme:

zahl = *zeiger * 3 + *zeiger - 2;

Der Nullzeiger

NULL ist eine invalide Speicheradresse, weswegen jeder Zeiger, wenn er nicht genutzt wird, am besten auf diesen Wert gesetzt wird.

int *zeiger = NULL;

Zeigerarithmetik

Ein Zeiger zeigt auf ein Array

Zuerst ist zu erwähnen, dass Zeiger auch auf Arrays zeigen und den Zeiger mit der bekannten Array-Syntax verwenden.

int zahlen[4] = { 1, 2, 3, 4 };
int *zeiger = zahlen; // zeiger zeigt nun auf Zahlen

std::cout << zeiger[1] << std::endl; // gibt 2 aus

Der Variablenname eines Arrays stellt desweiteren auch die Adresse des Arrays da. (Wie bei einem Zeiger)

Da eine Zelle eines Arrays wie eine Variable gehandhabt wird, kann auch auf eine Zelle gezeigt werden:

zeiger = &zahlen[2];
std::cout << *zeiger << std::endl; // gibt 3 aus
std::cout << zeiger[1] << std::endl; // gibt nicht 2 sondern 4 aus!

Es wurde also zeiger[1] zu zahlen[4]. Der Zeiger zeigt also auf zahlen[2] und mit zeiger[1] wurde prinzipiell zahlen[2 + 1] (also 3) aufgerufen.

Die Zeigerarithmetik

Mit den Adressen der Zeiger lässt sich also rechnen. Es stehen zwei Grundrechenarten (Addition und Subtraktion) zur Verfügung.
Es kann ein Zeiger mit einem konstanten Wert (einer Zahl/Integer) verrechnet werden oder mit zwei Zeiger des selben Types (deswegen ist der Typ des Zeigers erforderlich).

Durch dieses Wissen kann ein schnellerer Arraydurchlauf programmiert werden.

int zahlen[4] = { 1, 2, 3, 4 };

for(
    int *zeiger = zahlen;
    zeiger-zahlen /* die Adressen werden subtrahiert */ < sizeof(zahlen) / sizeof(zahlen[0]);
    zeiger++ /* die Adresse des Zeigers wird um sizeof(int) erhöht */)
{
    std::cout << *zeiger << std::endl;
}

(Das Konstrukt sizeof(zahlen) / sizeof(zahlen[0]) ermittelt die Arraygröße in Zellen.)

Dieser Zugriff ist um einiges schneller als zahlen[i], da bei zahlen[i] immer zuerst die ganze Adresse kalkuliert werden muss, während hier der Zugriff direkt erfolgt und danach nurnoch sizeof(int) Byte dazu gepakt werden.

Mit diesem lässt sich erschließen, dass *(zeiger + 3) und zeiger[3] identisch mit einander sind. (Zu beachten: Der Werteoperator ist höher gestellt als die mathematischen Operatoren, deswegen die Klammerung)

Zeiger mit unspezifiziertem Typen

Wenn die Typenüberwachung der Zeiger umgangen werden soll, so muss ein Zeiger vom Zeigertyp void angelegt werden.
Dieser Zeiger kann auf alle Datentypen zeigen. Da er aber selbst keinen hat, ist die Zeigerarithmetik nicht verfügbar.

int *zeiger;
void *void_zeiger = zeiger; // Funktioniert
zeiger = (int*)void_zeiger; // Hier muss der Typ gecastet werden

Der mathematische Teil

Der eulerschen Zahl spielt besonders in der Infinitesimalrechnung eine wichtige Rolle.
Mit der Hilfe der Grenzwertbildung lässt sich die Zahl berechnen.

Doch zwischen welchen Grenzen liegt die eulersche Zahl?
Dazu einmal zwei Graphen:

Die eulersche Zahl hat einen Winkel von 45° und muss somit zwischen 2 (mit einem Winkel von unter 45°) und 3 (mit einem Winkel von über 45°) liegen.
Doch wie kommt man nun an die Zahl?

Eine sehr ineffiziente Möglichkeit wäre, sich im Intervallverfahren der Zahl anzunähern, in dem man für zwei Intervalle jeweils den Winkel bestimmt.
Doch das Problem kann auch mathematisch angegangen werden:

e = e^{1} denn bei einer Expotentialfunktion gilt immer f(x = 1) = b^{x} = b.

Doch das führt immernoch nicht zu einem Ergebnis, deswegen wird jetzt das Potenzgesetz ((a^{s * r}) = (a^{s})^{r}) benötigt.
Zuerst muss das ganze Umgeformt werden, sodass eine Multiplikation entsteht:

e^{\frac{1}{n}*n}

Dabei kürzt sich n heraus, womit diese Form äquivalent zu e^{1} ist.
Nun wird das Potenzgesetz angewandt, womit das Ganze nun wie folgt ausschaut:
(e^{\frac{1}{n}})^{n}

Doch auf dem Rechner große Zahlen (z.B. n = 1.000.000) wird zu keinem gewünschten Ergebnis führen, selbst wenn die doppelte Genauigkeit angewandt wird.
Bereits bei einem Millionstel versagt eine Zahl mit doppelter Genauigkeit.
Um dieses Problem zu lösen, muss nun die Grenzwertbildung angewandt werden, womit Folgendes entsteht:
e = (1 + \frac{1}{n})^{n}

Jetzt sieht dies aus wie die dritte binomische Formel.
Wenn man das Ganze also umstellt erhält man:
e = 1 + 1 + \frac{n * (n-1)}{ 2 * 1 * n^{2}} + ... + \frac{n * (n-1) * ... * n-k_{n} }{ k_{n} * k_{n-1} * ... * k_{1} * n^{k_{n}}}

Praktisch gesehen hat dieser Schritt nun keinen Vorteil gebracht, da aber nur der Näherungswert gesucht ist, kann n * (n-1) * ... n-k_{n} mit n^{k_{n}} gekürzt werden, auch wenn die Zahlen sich minimal unterscheiden.
Somit bleibt am Ende nur folgende Formel übrig:
e = \sum_{n=0}^{\infty}\frac{1}{n!}

Die Programmierung

Als erstes ist eine Fakultätsfunktion notwendig. (Hier empfehle ich eine iterative Variante)

int fac(int n)
{
    int result = 1;
    if(!n)
        return 1;
    while(n > 1)
        result *= n--;
    return result;
}

Nun muss nurnoch die Summenformel angewandt werden. Dabei ist die Genauigkeit (precision) k + 2. (Die ersten beiden Fakultäten 0! und 1! sind bereits konstant berechnet (2))

double euler(unsigned short precision)
{
    double e = 2.0;
    unsigned short enumerator = 2;
    while(precision--)
        e += float(1) / fac(enumerator++);
    return e;
}

So lässt sich schnell die eulersche Zahl bei Bedarf berechnen.

Fehlermeldung:

GCC: argument of type 'int (A::)(int)' does not match 'int (*)(int)' 

Das Problem:

class A
{
    public:
        int add_y(int a)
        {
            return a+y;
        }

	int y;
};

int main()
{
    A x;
    int (*ptr)(int) = x.add_y; // <-- Fehlermeldung

    return 0;
}

ptr soll auf die Methode add_y der Klasse A aus der Instanz x zeigen.
Genau dieses Konstrukt funktioniert allerdings nicht.

Der Grund:

Dies hat mit dem Aufbau einer Klasse zutun, den im Prinzip liegt nur eine Struktur (struct) vor,
in der die Variablen und evt. noch virtuelle Methoden (vtable) aufgelistet sind.
D.h. alle Instanzen einer Klasse nutzen reell nur eine Methode. (Dabei ist der erste Parameter ein „unsichtbarer“ Pointer auf die Klasse)

Die Lösung:

Nun gibt es diverse Lösungswege. Man kann einen static Member zur Klasse hinzufügen oder eine Funktion als wrapper verwenden.
Der „schönere“ Weg dürfte aber das Verwenden eines static Members sein.

Dieser benötigt neben der normalen Parametrierung auch noch den Zeiger auf die Klasse (quasi den this pointer).

static int add_y_wrapper(class A *self, int a) {
     return self->add_y(a); // ruft add_y der Klasse auf
}

Nun kann der Zeiger auf den static Member zeigen:

int (*ptr)(class A*, int) = A::add_y_wrapper;

Ein Beispielaufruf mit der Instanz x wäre:

ptr(&x, 3);