Heim  >  Artikel  >  Backend-Entwicklung  >  Casting in C++

Casting in C++

黄舟
黄舟Original
2017-02-06 13:43:521802Durchsuche

F: Was ist eine C-Stilkonvertierung? Was sind static_cast, dynamische_cast und reinterpret_cast? Was ist der Unterschied? Warum sollten wir darauf achten?


A: Die Bedeutung der Konvertierung besteht darin, die Darstellung einer Variablen zu ändern, indem der Typ der Variablen in einen anderen Typ geändert wird. Um ein einfaches Objekt in ein anderes umzuwandeln, würden Sie herkömmliche Typkonvertierungsoperatoren verwenden.


Um beispielsweise einen Zeiger vom Typ doppelte Gleitkommazahl in eine Ganzzahl umzuwandeln:

Code

int i;
double d;
i = (int) d;


oder:

i = int (d);


funktioniert gut für einfache Typen mit standardmäßig definierten Konvertierungen. Allerdings können solche Konvertierungsoperatoren auch beliebig auf Klassen und Klassenzeiger angewendet werden. Der ANSI-C++-Standard definiert vier neue Konvertierungsoperatoren: „reinterpret_cast“, „static_cast“, „dynamic_cast“ und „const_cast“, die die Typkonvertierung zwischen Klassen steuern sollen.


Code:

reinterpret_cast<new_type>(expression)
dynamic_cast<new_type>(expression)
static_cast<new_type>(expression)
const_cast<new_type>(expression)


1 reinterpret_cast


reinterpret_cast Konvertiert einen Zeiger in einen Zeiger anderer Typen. Es ermöglicht auch die Konvertierung von einem Zeiger in einen Integer-Typ. umgekehrt. (Anmerkung: Ist der spezifische Adresswert des Zeigers ein ganzzahliger Wert?)


Dieser Operator kann zwischen nicht verwandten Typen konvertieren. Das Ergebnis der Operation ist einfach eine binäre Kopie des Werts von einem Zeiger auf einen anderen. Inhalte, auf die zwischen Typen verwiesen wird, unterliegen keiner Typprüfung oder Konvertierung. Wenn es sich um eine Kopie eines Zeigers auf eine Ganzzahl handelt, ist die Interpretation des Inhalts systemabhängig, sodass eine Implementierung nicht sinnvoll ist. Ein Zeiger, der in einen ganzzahligen Typ konvertiert wurde, der groß genug ist, um ihn aufzunehmen, kann in einen gültigen Zeiger zurückkonvertiert werden.


Code:

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B *>(a);


reinterpret_cast behandelt alle Zeigertypkonvertierungen genauso wie herkömmliche Typkonvertierungen.


2 static_cast


static_cast ermöglicht beliebige implizite Konvertierungs- und Rückkonvertierungsaktionen. (auch wenn es nicht implizit sein darf)


bedeutet, dass ein Zeiger vom Unterklassentyp in einen Zeiger vom Oberklassentyp konvertiert werden kann (dies ist ein gültiges Implizit). Konvertierung) und kann gleichzeitig auch die gegenteilige Aktion ausführen: eine übergeordnete Klasse in ihre Unterklasse konvertieren. In diesem letzten Beispiel wird die konvertierte übergeordnete Klasse nicht auf Konsistenz mit dem Zieltyp überprüft.


Code:

class Base {};
class Derived : public Base {};
 
Base *a = new Base;
Derived *b = static_cast<Derived *>(a);


static_cast Zusätzlich zu Betriebstypzeigern kann static_cast auch zur Ausführung verwendet werden die Anzeige der Typdefinitionsformelkonvertierung und Standardkonvertierung zwischen Grundtypen:


Code:

double d = 3.14159265;
int i = static_cast<int>(d);


3dynamic_cast


dynamic_cast wird nur für Zeiger und Referenzen auf Objekte verwendet. Bei Verwendung mit polymorphen Typen ermöglicht es beliebige implizite Typkonvertierungen und umgekehrt. Im Gegensatz zu static_cast prüft Dynamic_cast im letzteren Fall (Hinweis: der umgekehrte Prozess der impliziten Konvertierung), ob die Operation gültig ist. Das heißt, es prüft, ob die Konvertierung ein gültiges vollständiges angefordertes Objekt zurückgibt.


Die Erkennung erfolgt zur Laufzeit. Wenn der konvertierte Zeiger nicht wie angefordert ein gültiger vollständiger Objektzeiger ist, ist der Rückgabewert NULL.


Code:

class Base { virtual dummy() {} };
class Derived : public Base {};
 
Base* b1 = new Derived;
Base* b2 = new Base;
 
Derived* d1 = dynamic_cast<Derived *>(b1); // succeeds
Derived* d2 = dynamic_cast<Derived *>(b2); // fails: returns &#39;NULL&#39;


Wenn eine Typumwandlung für einen Referenztyp durchgeführt wird und diese Konvertierung nicht möglich ist, wird ein bad_cast-Ausnahmetyp ausgelöst:


Code:

class Base { virtual dummy() {} };
class Derived : public Base { };
 
Base* b1 = new Derived;
Base* b2 = new Base;
 
Derived d1 = dynamic_cast<Derived &*>(b1); // succeeds
Derived d2 = dynamic_cast<Derived &*>(b2); // fails: exception thrown

4 const_cast


Dieser Konvertierungstyp manipuliert das const-Attribut des übergebenen Objekts, indem er es entweder setzt oder entfernt:


Code:

class C {};
const C *a = new C;
 
C *b = const_cast<C *>(a);


Die anderen drei Operatoren können die Konstanz eines Objekts nicht ändern. Hinweis: „const_cast“ kann auch den flüchtigen Qualifizierer eines Typs ändern.


Jede der vier Cast-Formen von C++ ist für einen bestimmten Zweck geeignet


dynamic_cast wird hauptsächlich zur Ausführung verwendet „Sicheres Downcasting“, also die Bestimmung, ob ein Objekt einem bestimmten Typ in einer Vererbungshierarchie angehört. Es ist die einzige Umwandlung, die nicht mit der Syntax des alten Stils durchgeführt werden kann, und es ist die einzige Umwandlung, die möglicherweise erhebliche Laufzeitkosten verursacht.

static_cast kann verwendet werden, um implizite Konvertierungen zu erzwingen (z. B. nicht konstante Objekte in konstante Objekte, int in double usw.), und es kann auch verwendet werden, um viele solcher Konvertierungen umzukehren (z. B. a Der void*-Zeiger wird in einen typisierten Zeiger konvertiert, und ein Basisklassenzeiger wird in einen abgeleiteten Klassenzeiger konvertiert. Er kann jedoch kein const-Objekt in ein nicht-const-Objekt konvertieren (das kann nur const_cast), was C am nächsten kommt -Stil konvertieren.

const_cast wird im Allgemeinen verwendet, um die Beseitigung der Objektkonstanz zu erzwingen. Es ist die einzige Besetzung im C++-Stil, die dies kann.

reinterpret_cast ist für Low-Level-Casts gedacht, die zu implementierenden (d. h. nicht tragbaren) Ergebnissen führen, z. B. der Konvertierung eines Zeigers in eine Ganzzahl. Außerhalb von Low-Level-Code sollten solche Umwandlungen äußerst selten sein.

Das Obige ist der Inhalt der erzwungenen Typkonvertierung in C++. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn