2010-06-14 19 views
5

In C# è possibile utilizzare as per convertire un tipo o ottenere nulla:Equivalente al comando C# 'as' in C++?

Object o = Whatever(); 
String s = o as String; 

C'è un modo semplice simile a raggiungere questo obiettivo in C++?

Utilizzo Visual Studio 2010, se è importante.

[Aggiornamento]: Ricorda che c'è una differenza molto importante tra il casting e l'utilizzo di as. Casting (almeno in C#) un'eccezione se il tipo non corrisponde:

Object o = null; 
String s = (String)o; // Will crash. 
+0

Nessuna delle risposte che suggeriscono usando 'dynamic_cast' siano corrette. La parola chiave C# è un'operazione di conversione, ma 'dynamic_cast' è un cast. –

+1

@Jon Dibling - 'as' è un cast. ha successo solo se il cast è valido. – sylvanaar

+0

@sylvanaar: in base alla specifica C#, l'operatore di cast e la parola chiave 'as' eseguono entrambe le conversioni. Vedi 7.9.11 e 7.6.6 –

risposta

9

In C++, questo sarebbe un dynamic_cast, se si dispone di una gerarchia in cui Object è il genitore e String è il figlio.

Object * p = createMyObject(); 
String * s = dynamic_cast<String *>(p); 
if(s) 
{ 
    ... 
} 

dinamico colata un puntatore restituirà un puntatore all'oggetto se il cast è possibile, o un puntatore nullo se non.

Inoltre, il casting dinamico di un riferimento restituirà un riferimento all'oggetto se il cast è possibile o genera un'eccezione.

+4

La sintassi è errata. dovrebbe essere: 'dynamic_cast (p);' e dovresti notare che String deve essere derivata da Object. –

+0

Infatti, ho aggiunto il puntatore. –

+3

Come estensione di ciò che Neil ha detto, non esiste una classe base comune da cui derivi automaticamente tutte le classi in C++. Alcune librerie hanno una classe così centrale, come Qt e wxWidgets, ma queste sono derivate esplicitamente, direttamente o tramite un'altra classe. – blwy10

3

Usa dynamic_cast<type>(), ma funzionerà solo con i puntatori, non oggetti statici.

+4

Con i puntatori, si ottiene un puntatore nullo se il cast non è valido. Funziona con i riferimenti, ma genera un'eccezione se non valida. –

5

In C++ non esiste una classe di oggetti di base, quindi in generale non c'è modo di farlo. È comunque possibile farlo per le gerarchie specifiche:

struct A { 
    virtual ~A() {} 
}; 

struct B : public A { 
}; 

A * p = Something();  // Something() may return an A * or a B * 
B & b = dynamic_cast <B&>(*p); 

Il cast dinamico un'eccezione se p non punta a qualcosa che può tranquillamente essere convertito in un riferimento B.

+0

solo per confermare, possiamo dynamic_cast su riferimento? –

+0

@Dbger Possiamo certamente. –

+0

Dovremmo notare le differenze di casting di un riferimento per lanciare un puntatore. Se il dynamic_cast fallisce: su un puntatore viene restituito NULL; su un riferimento viene generata un'eccezione –

2

Da quello che posso leggere da: C# Programmer's Reference: AS l'operatore as svolge la stessa attività di dynamic_cast in C++.

+1

No, sicuramente non lo è. '# C 'è una conversione. dynamic_cast è un cast. –

+0

Considerando ciò dal riferimento del programmatore C#: * L'operatore as è come un cast eccetto per il fatto che produce null sull'errore di conversione invece di generare un'eccezione. * E: 'espressione come tipo' è equivalente a:' expression is type? (type) espressione: (type) null'. Direi che l'operatore 'as' somiglia di più al' dynamic_cast', specialmente dal momento che 'as' non è in grado di eseguire conversioni definite dall'utente. –

+0

Lo capisco, ma la domanda riguarda un'operazione equivalente in C++, quindi anche se non è importante distinguere tra "cast" e "convert" in un linguaggio come C#, c'è una grande differenza in C++. Quindi è importante essere chiari. Hai detto te stesso, "come è un cast" - non "come * è * come cast". E la specifica C# è ugualmente esplicita: (7.6.6): "Un'espressione cast viene utilizzata per convertire esplicitamente un'espressione in un determinato tipo" e (7.9.11): "L'operatore as viene utilizzato per convertire esplicitamente un valore in un determinato tipo di riferimento o tipo nullable "Queste sono conversioni, non cast. –

-1

In C# la as parola chiave converte un valore in un altro tipo. C'è un codice che supporta questa conversione (probabilmente nel runtime C#). Questo non è un cast.

Per la maggior parte non è possibile utilizzare dynamic_cast o qualsiasi altro tipo di cast in C++ per realizzare questo, perché le conversioni e le conversioni non sono la stessa cosa. Dico 'per la maggior parte' perché alcuni tipi possono essere convertiti utilizzando static_cast, per convertire un int in un float ma questa è ancora una conversione, non un cast. Inoltre, se hai introdotto un sistema di tipi in cui tutto è derivato da una classe base Object -like con questa funzionalità di conversione, potresti essere in grado di costruire un meccanismo per supportare questa conversione utilizzando dynamic_cast, ma avresti dovuto scrivere questo meccanismo e questo non sembra essere quello che stai cercando di fare.

Non c'è niente di integrato nel C++ che farà questa conversione per voi; in altre parole, non esiste C++ equivalente alla parola chiave C# as.

Se si desidera eseguire questa conversione, è spesso possibile utilizzare i flussi:

#include <sstream> 
#include <string> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    float f = 42.0f; 
    stringstream ss; 
    ss << f; 
    string s = ss.str(); 
    cout << "Float: " << f << ", String '" << s << "'"; 

    return 0; 
} 

<sstream> fa parte della ++ standard C, quindi in questo senso si potrebbe considerare di essere 'in lingua'.

L'utilizzo degli stream per eseguire questa conversione può essere piuttosto goffo. Boost offerslexical_cast che può essere utilizzato per eseguire queste semplici conversioni con meno codice:

#include <sstream> 
#include <iostream> 
#include <boost\lexical_cast.hpp> 

using namespace std; 

int main() 
{ 
    string s = "42"; 
    float f = boost::lexical_cast<float>(s); 

    cout << "Float: " << f << ", String '" << s << "'"; 

    return 0; 
} 
+0

Qual è la differenza tra il casting e la conversione di un tipo di riferimento in C#? – sylvanaar

+0

@sylvanaar: In C# non sembra esserci un vero 'cast' nel senso C++. In C++ un cast significa "finta variabile x è di tipo Y", ma secondo la specifica C#, (7.6.6) "Un'espressione cast viene usata per convertire esplicitamente un'espressione in un dato tipo." e (7.9.11) "L'operatore as viene utilizzato per convertire esplicitamente un valore in un determinato tipo di riferimento o in un tipo nullable. A differenza di un'espressione cast (§7.6.6), l'operatore as non genera mai un'eccezione. la conversione non è possibile, il valore risultante è nullo." –

+0

@sylvanaar: Se hai downvoted la mia risposta, devi pensare che sia sbagliato.Che cosa, esattamente, è sbagliato nel mio post? –