Advanced   Java   Services Weitere C++11 Features



Weitere C++11 Features





auto

Falls der Compiler aus der rechten Seite einer Zuweisung den Typ der Variablen ermitteln kann, kann man nun das (umfunktionierte) Schlüsselwort auto verwenden.

/*
 * auto
 */
#include <list>

void feature01()
{
   cout << "feature01 auto" << endl;
   auto x = 17;
   auto y = 23.45;
   auto poi = malloc(42);
   std::list<int> intlist (5, 42);  // five ints with value 42
   for (auto /*std::list<int>::iterator*/ it = intlist.begin(); it != intlist.end(); it++)
       std::cout << *it << ' ';
}

nullptr

Für NULL gibt es eine implizite Typkonvertierung nach 0 (Typ int), was zu Mißdeutungen führen kann. Auch kann man etwa einfach int *poi = 0; schreiben. Das neue SDchlüsselwort nullptr steht für das Literal std::nullptr_t. Dadurch wird eine implizite Typkonvertierung vermieden.

void feature02()
{
   // möglich, aber nicht gut
   int i = NULL;
   int *ipoi = 0;

   cout << "feature02 nullptr" << endl;
   int* p1 = NULL;
   int* p2 = nullptr;
   cout << "(NULL == nullptr) : " << (NULL == nullptr) << endl;  // 1
   // int j = nullptr; // cannot convert nullptr to int
   cout << (int*)nullptr << endl;  // muß gecastet werden, sonst mehrdeutig
}

override und final

Das neue optionale Schlüsselwort override steht am Ende einer Signatur und veranlaßt den Compiler zu einer Überprüfung der Signatur der entsprechenden Methode der Elternklasse. So können Fehler vermieden werden. So kann der Compiler im nachfolgenden Beispiel feststellen, daß die Signatur nicht der der Elternmethode entspricht.

class B
{
public:
   virtual void f(short) {}
};

class D : public B
{
public:
   virtual void f(int) override  // override muß am ende der signatur stehen
   {}
};

Auch das neue optionale Schlüsselwort final steht am Ende einer Signatur und verhindert eine Überschreibung der Methode in der Kindklasse. Im nachfolgenden Beispiel verweigert der Compiler das Überschreiben der Methode in der Klasse CC. Man kann auch beide Schlüsselwörter kombinieren.

class AA
{
public:
   virtual void f(int) {}
};

class BB : public AA
{
public:
   virtual void f(int) final override {}
};

class CC : public BB
{
public:
   virtual void f(int) {}  // nicht mehr möglich, Compilerfehler
};

Die Reihenfolge von override und final ist egal, aber natürlich ist final override besser lesbar.


enum classes

enum Klassen erhöhen die Typsicherheit, da sie nicht mehr typverträglich zu int sind.

enum class Season {SPRING, SUMMER, AUTUMN, WINTER};

void feature05()
{
   cout << "feature05: enum classes" << endl;
   Season sea = Season::SPRING;
   //int i = sea; // cannot convert 'Season' to 'int'
   int i = (int)sea; // OK
}

std::begin() und std::end()

std::begin() und std::end() sind zwei neue Funktionstemplates. Sie liefern einen Iterator, der auf das erste bzw. auf das letzte Element in einem STL-Container zeigt. Damit vereinfacht sich das Iterieren durch einen Container.

/*
 * std::begin() and std::end()
 */
#include <iterator>

void feature06()
{
   cout << "feature06: std::begin() and std::end()" << endl;

   std::list<int> intlist (4,17);  // four ints with value 17
   for (auto /*std::list<int>::iterator*/ it = intlist.begin(); it != intlist.end(); it++)
       std::cout << *it << ' ';
   cout << endl;

   // mit C++11 auch so
   for (auto it = std::begin(intlist); it != std::end(intlist); it++)
       std::cout << *it << ' ';
   cout << endl;
}