Operatore static_cast
Converte un'espressione nel tipo di type-id, in base solo ai tipi presenti nell'espressione.
Sintassi
static_cast <type-id> ( expression )
Osservazioni:
Nel linguaggio C++ standard non viene eseguito alcun controllo dei tipi in fase di esecuzione a garanzia della sicurezza della conversione. In C++/CX vengono eseguiti due controlli, uno in fase di compilazione, l'altro in fase di esecuzione. Per ulteriori informazioni, vedi Cast.
L'operatore static_cast
può essere usato per operazioni quali la conversione di un puntatore a una classe base in un puntatore a una classe derivata. Questi tipi di conversioni non sempre sono sicure.
In generale, si usa static_cast
quando si desidera convertire tipi di dati numerici, ad esempio enumerazioni in ints o ints in float, e si è certi dei tipi di dati coinvolti nella conversione. static_cast
le conversioni non sono sicure come dynamic_cast
le conversioni, perché static_cast
non esegue alcun controllo del tipo di runtime, mentre dynamic_cast
lo fa. Un dynamic_cast
oggetto a un puntatore ambiguo avrà esito negativo, mentre restituisce static_cast
come se non si fosse verificato alcun problema. Questo può essere pericoloso. Anche se dynamic_cast
le conversioni sono più sicure, dynamic_cast
funziona solo su puntatori o riferimenti e il controllo del tipo di runtime è un sovraccarico. Per altre informazioni, vedere Operatore dynamic_cast.
Nell'esempio seguente la riga D* pd2 = static_cast<D*>(pb);
non è sicura perché D
può contenere campi e metodi non presenti in B
. Tuttavia, la riga B* pb2 = static_cast<B*>(pd);
è una conversione sicura perché D
contiene sempre tutti B
.
// static_cast_Operator.cpp
// compile with: /LD
class B {};
class D : public B {};
void f(B* pb, D* pd) {
D* pd2 = static_cast<D*>(pb); // Not safe, D can have fields
// and methods that are not in B.
B* pb2 = static_cast<B*>(pd); // Safe conversion, D always
// contains all of B.
}
A differenza di dynamic_cast, non viene eseguito alcun controllo di runtime sulla static_cast
conversione di pb
. L'oggetto a cui fa riferimento pb
non può essere un oggetto di tipo D
, nel qual caso l'utilizzo di *pd2
può diventare molto rischioso. Ad esempio, la chiamata a una funzione membro della classe D
, ma non della classe B
potrebbe tradursi in una violazione di accesso.
Gli dynamic_cast
operatori e static_cast
spostano un puntatore in una gerarchia di classi. Tuttavia, static_cast
si basa esclusivamente sulle informazioni fornite nell'istruzione cast e pertanto non può essere sicuro. Ad esempio:
// static_cast_Operator_2.cpp
// compile with: /LD /GR
class B {
public:
virtual void Test(){}
};
class D : public B {};
void f(B* pb) {
D* pd1 = dynamic_cast<D*>(pb);
D* pd2 = static_cast<D*>(pb);
}
Se pb
punta veramente a un oggetto di tipo D
, pd1
e pd2
otterranno lo stesso valore. Otterranno anche lo stesso valore se pb == 0
.
Se pb
punta a un oggetto di tipo B
e non alla classe completa D
, dynamic_cast
saprà abbastanza per restituire zero. Tuttavia, static_cast
si basa sull'asserzione del programmatore che pb
punta a un oggetto di tipo D
e restituisce semplicemente un puntatore a tale oggetto presunto D
.
Di conseguenza, static_cast
può eseguire l'inversa delle conversioni implicite, nel qual caso i risultati non sono definiti. Viene lasciato al programmatore verificare che i risultati di una static_cast
conversione siano sicuri.
Questo comportamento si applica anche a tipi diversi dai tipi di classe. Ad esempio, static_cast
può essere usato per eseguire la conversione da un int a un oggetto char
. Tuttavia, il risultato char
potrebbe non avere bit sufficienti per contenere l'intero int
valore. Anche in questo caso, viene lasciato al programmatore per verificare che i risultati di una static_cast
conversione siano sicuri.
L'operatore static_cast
può essere usato anche per eseguire qualsiasi conversione implicita, incluse le conversioni standard e le conversioni definite dall'utente. Ad esempio:
// static_cast_Operator_3.cpp
// compile with: /LD /GR
typedef unsigned char BYTE;
void f() {
char ch;
int i = 65;
float f = 2.5;
double dbl;
ch = static_cast<char>(i); // int to char
dbl = static_cast<double>(f); // float to double
i = static_cast<BYTE>(ch);
}
L'operatore static_cast
può convertire in modo esplicito un valore integrale in un tipo di enumerazione. Se il valore del tipo integrale non rientra nell'intervallo dei valori di enumerazione, il valore di enumerazione risultante sarà indefinito.
L'operatore static_cast
converte un valore del puntatore Null nel valore del puntatore Null del tipo di destinazione.
Qualsiasi espressione può essere convertita in modo esplicito in tipo void dall'operatore static_cast
. Il tipo void di destinazione può includere facoltativamente l'attributo const
, volatile
o __unaligned
.
L'operatore static_cast
non può eseguire il cast degli const
attributi , volatile
o __unaligned
. Per informazioni sulla rimozione di questi attributi, vedere const_cast Operator .See const_cast Operator for information on removing these attributes.
C++/CLI: a causa del rischio di eseguire cast non controllati su un Garbage Collector di rilocazione, l'uso di static_cast
deve essere solo nel codice critico per le prestazioni quando si è certi che funzioni correttamente. Se è necessario usare static_cast
in modalità di rilascio, sostituirlo con safe_cast nelle compilazioni di debug per garantire l'esito positivo.