Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Quatro operadores de conversão diferentes se aplicam aos tipos do Windows Runtime: Operador static_cast, Operador dynamic_cast, Operador safe_cast e Operador de reinterpret_cast.
safe_cast e static_cast lançam exceção quando a conversão não pode ser executada; static_cast Operator também realiza a verificação de tipo em tempo de compilação.
dynamic_cast retornará nullptr se não converter o tipo. Embora reinterpret_cast retorne um valor não nulo, ele poderá ser inválido. Por esse motivo, é recomendável não usar reinterpret_cast a menos que você saiba que a conversão funcionará. Além disso, recomendamos que você não use conversões no estilo C em seu código C++/CX porque elas são idênticas a reinterpret_cast.
O compilador e o runtime também executam conversões implícitas - por exemplo, em operações de conversão boxing quando um tipo de valor ou um tipo interno é transmitido como argumentos para um método cujo tipo de parâmetro é Object^. Em tese, uma conversão implícita nunca deve causar uma exceção no tempo de execução; se o compilador não puder executar uma conversão implícita, ele gerará um erro no tempo de compilação.
O Windows Runtime é uma abstração sobre COM, que usa os códigos de erro HRESULT em vez de exceções. Em geral, o Platform::InvalidCastException indica um erro COM de baixo nível de E_NOINTERFACE.
static_cast
Um static_cast é verificado no tempo de compilação para determinar se há uma relação de herança entre os dois tipos. A conversão causará um erro do compilador se os tipos não estiverem relacionados.
Um static_cast em uma classe ref também faz com que uma verificação de tempo de execução seja executada.
static_cast em uma classe de referência pode transmitir a verificação de tempo de compilação, mas ainda falhar no tempo de execução; Platform::InvalidCastException é lançada nesse caso. Geralmente, você não precisa tratar essas exceções, pois quase sempre elas indicam erros de programação que você pode eliminar durante as fases de desenvolvimento e teste.
Use static_cast se o código declarar explicitamente uma relação entre os dois tipos e se você estiver certo de que a conversão funcionará.
interface class A{};
public ref class Class1 sealed : A { };
// ...
A^ obj = ref new Class1(); // Class1 is an A
// You know obj is a Class1. The compiler verifies that this is possible, and in C++/CX a run-time check is also performed.
Class1^ c = static_cast<Class1^>(obj);
safe_cast
O operador safe_cast faz parte do Windows Runtime. Ele executa uma verificação de tipo no tempo de execução e gera Platform::InvalidCastException se houver falhas na conversão. Use safe_cast quando uma falha em tempo de execução indique uma condição excepcional. A principal finalidade do safe_cast é ajudar a identificar erros de programação durante as fases de desenvolvimento e teste no ponto em que eles ocorrem. Você não precisa lidar com a exceção porque a própria exceção não tratada identifica o ponto de falha.
Use safe_cast se o código não declarar a relação e você tiver certeza de que a conversão funcionará.
// A and B are not related
interface class A{};
interface class B{};
public ref class Class1 sealed : A, B { };
// ...
A^ obj = ref new Class1();
// You know that obj's backing type implements A and B, but
// the compiler can't tell this by comparing A and B. The run-time type check succeeds.
B^ obj2 = safe_cast<B^>(obj);
dynamic_cast
Use dynamic_cast quando converter um objeto (mais especificamente, ^) em um tipo mais derivado, e esperar que o objeto de destino seja ocasionalmente nullptr ou que a conversão falhe, e você desejar tratar essa condição como um caminho do código regular, em vez de uma exceção. Por exemplo, no modelo de projeto Blank App (Universal Windows), o método em OnLaunched app.xaml.cpp usa dynamic_cast para testar se a janela do aplicativo tem conteúdo. Não é um erro se não tiver conteúdo; é uma condição esperada.
Windows::Current::Content é um Windows::UI::XAML::UIElement , e a conversão é em Windows::UI.XAML::Controls::Frame, que é um tipo mais derivado na hierarquia de herança.
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args)
{
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
// Do not repeat app initialization when the window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
rootFrame = ref new Frame();
// ...
}
}
Outro uso de dynamic_cast é investigar um Object^ para determinar se ele contém um tipo de valor demarcado. Nesse caso, você tenta um dynamic_cast<Platform::Box> ou um dynamic_cast<Platform::IBox>.
dynamic_cast e referências de acompanhamento (%)
Você também pode aplicar um dynamic_cast em uma referência de acompanhamento, mas nesse caso a conversão se comporta como safe_cast. Ela gera Platform::InvalidCastException em caso de falha porque uma referência de acompanhamento não pode ter um valor de nullptr.
reinterpret_cast
Recomendamos que você não use reinterpret_cast porque nem uma verificação de tempo de compilação nem uma verificação de tempo de execução são executadas. Na pior das hipóteses, a possibilita que erros reinterpret_cast de programação passem despercebidos no momento do desenvolvimento e causem erros sutis ou catastróficos no comportamento do seu programa. Dessa forma, recomendamos que você use reinterpret_cast apenas em casos raros em que for necessário converter tipos não relacionados e você tiver certeza de que a conversão funcionará. Um exemplo de uso incomum é converter um tipo do Windows Runtime ao seu tipo de ABI subjacente. Isso significa que você está assumindo o controle da contagem de referência para o objeto. Para fazer isso, recomendamos que você use o ponteiro inteligente classe ComPtr . Caso contrário, você deverá chamar especificamente a versão na interface. O exemplo a seguir mostra como uma classe de referência pode ser convertida em IInspectable*.
#include <wrl.h>
using namespace Microsoft::WRL;
auto winRtObject = ref new SomeWinRTType();
ComPtr<IInspectable> inspectable = reinterpret_cast<IInspectable*>(winRtObject);
// ...
Se você usar reinterpret_cast para converter uma interface do Windows Runtime em outra, o objeto será liberado duas vezes. Portanto, somente use essa conversão quando estiver convertendo em uma interface de extensões de componente não C++.
Tipos de ABI.
Os tipos de ABI permanecem ativos em cabeçalhos no Windows SDK. Convenientemente, os cabeçalhos são nomeados com namespaces - por exemplo,
windows.storage.h.Os tipos de ABI permanecem ativos em uma ABI de namespace especial - por exemplo,
ABI::Windows::Storage::Streams::IBuffer*.Conversões entre um tipo de interface do Windows Runtime e seu tipo de ABI equivalente são sempre seguras, ou seja,
IBuffer^aABI::IBuffer*.Uma classe do Tempo de Execução do Windows sempre deve ser convertida em
IInspectable*ou em sua interface padrão, se isso for conhecido.Depois de converter em tipos de ABI, você possui o tempo de vida do tipo e deverá seguir as regras COM. Recomendamos usar
WRL::ComPtrpara simplificar o gerenciamento de tempo de vida de ponteiros de ABI.
A tabela a seguir resume os casos em que é seguro usar reinterpret_cast. Em todos os casos, a conversão é segura em ambas as direções.
| Converter de, converter em | Converter em, converter de |
|---|---|
HSTRING |
String^ |
HSTRING* |
String^* |
IInspectable* |
Object^ |
IInspectable** |
Object^* |
IInspectable-derived-type* |
same-interface-from-winmd^ |
IInspectable-derived-type** |
same-interface-from-winmd^* |
IDefault-interface-of-RuntimeClass* |
same-RefClass-from-winmd^ |
IDefault-interface-of-RuntimeClass** |
same-RefClass-from-winmd^* |