C++ Tutorial

 Typkonvertierungen

Mittels Typkonvertierung wird der ursprüngliche Datentyp eines Datums oder Ausdrucks in einen anderen Datentyp konvertiert. 

Folgende explizite Typkonvertierungen stehen zur Verfügung:

  • const_cast<DTYP> (AUSDRUCK)
  • static_cast<DTYP> (AUSDRUCK)
  • dynamic_cast<DTYP> (AUSDRUCK)
  • reinterpret_cast<DTYP> (AUSDRUCK)

DTYP ist der neue Datentyp, in den AUSDRUCK konvertiert werden soll. Jede dieser Typkonvertierungen wird für eine spezielle Konvertierung eingesetzt.

const_cast Konvertierung

Die const_cast Konvertierung dient dazu, den const oder volatile Modifizierer von einem Datentyp zu entfernen oder ihn hinzuzufügen (volatile wird später noch erklärt).

// Daten definieren
const char *pConst {"Hallo"};
int var = 10;
volatile int *pvar = &var;
// Konvertierung const char* -> char*
// Achtung! Je nach System kann diese Konvertierung
// schwerwiegende Folgen haben
char *pNonConst = const_cast<char*>(pConst);
// Konvertierung volatile int* -> int*
int *pNonVolatile = const_cast<int*>(pvar);

static_cast Konvertierung

Die static_cast Konvertierung wird eingesetzt, um zwischen Ganzzahl-Datentypen und Gleitkomma-Datentypen zu konvertieren oder einen void-Zeiger in einen beliebigen anderen Zeiger zu konvertieren.

// int-Daten
int dividend = 10, divisor = 3;
// Konvertierung int -> float fuer Gleitkomma-Berechnung
auto result = static_cast<float>(dividend) / static_cast<float>(divisor);
// void-Zeiger definieren/initialisieren
void* pvoid = &dividend;
// Konvertierung void* -> short*
short* pshort = static_cast<short*>(pvoid);

Ebenfalls wird der static_cast Operator eingesetzt, um Objektzeiger zu konvertieren, deren Klassen in einer Beziehung zueinanderstehen. Diese Konvertierung wird im Kapitel Typkonvertierungen auf Klassenzeiger später behandelt.

reinterpret_cast Konvertierung

Die reinterpret_cast Konvertierung wird zum einen für die Konvertierung zwischen verschiedenen Zeigertypen und zum anderen für die Konvertierung von Integer-Daten in Zeiger und umgekehrt eingesetzt.

#include <iostream>
#include <format>

int main()
{
   // int-Variablen definieren/initialisieren
   int var1 = 10, var2 = 3;
   // static_cast Konvertierung bei int-Division
   auto res1 = var1 / var2;
   auto res2 = static_cast<float>(var1 / var2);
   auto res3 = static_cast<float>(var1) / static_cast<float>(var2);
   std::cout << std::format("var1 / var2 = {}\n"
                           "static_cast<float>(var1 / var2) = {}\n"
                           "static_cast<float>(var1) / static_cast<float>(var2) = {}\n",
                            res1, res2, res3);
   // reinterpret_cast Konvertierung
   // int* nach unsigned char*
   unsigned char* bytes = reinterpret_cast<unsigned char*>(&var1);
   std::cout << std::format("int var1 = {}\nUnd in Bytes: {:x},", var1, *bytes);
   bytes++;
   std::cout << std::format("{:x},", *bytes);
   bytes++;
   std::cout << std::format("{:x},", *bytes);
   bytes++;
   std::cout << std::format("{:x},", *bytes);
}

dynamic_cast Konvertierung

Die dynamic_cast Konvertierung wird später bei der Behandlung von abgeleiteten Klassen beschrieben, da sie nur in diesem Zusammenhang von Bedeutung ist. Sie ist nur der Vollständigkeit wegen an dieser Stelle erwähnt.

Automatische Typkonvertierungen (Promotions)

Viele alltägliche Konvertierungen führt der Compiler automatisch durch, wenn dadurch keine Information verloren geht.

Integral Promotion

Werte vom Datentyp char, (un-)signed char und (un-)signed short können vom Compiler auf den Datentyp int erweitert werden, wenn dadurch der gesamte Wertebereich des Original-Datentyps abgedeckt wird. Ist dies nicht der Fall, so wird eine Anpassung auf einen unsigned int Datentyp versucht. Ebenfalls kann ein bool-Wert in einen int-Wert konvertiert werden, wobei true gleich 1 und false gleich 0 ist.

Floating-Integral Konvertierung

Ein Gleitkomma-Datum kann in ein Integer-Datum konvertiert werden, wobei die Nachkommastellen abgeschnitten werden.

Zeiger Konvertierungen

Ein Zeiger eines beliebigen Datentyps kann immer in einen void-Zeiger (typloser Zeiger) konvertiert werden. Außerdem kann ein Zeiger auf eine abgeleitete Klasse stets in einen Zeiger auf seine Basisklasse konvertiert werden. Dieser Sachverhalt spielt später noch eine wichtige Rolle.