Aracılığıyla paylaş


Atama (C++/CX)

Windows Çalışma Zamanı türleri için dört farklı atama işleci uygulanır: static_cast İşleci, dynamic_cast İşleci, safe_cast İşleci ve reinterpret_cast İşleci. dönüştürme gerçekleştirilemiyorsa safe_cast ve static_cast bir özel durum oluşturur; static_cast İşleci ayrıca derleme zamanı türü denetimi gerçekleştirir. dynamic_cast türü dönüştüremezse döndürür nullptr . Null olmayan bir değer döndürse reinterpret_cast de geçersiz olabilir. Bu nedenle, atamanın başarılı olacağını bilmiyorsanız kullanmamanızı reinterpret_cast öneririz. Ayrıca, C++/CX kodunuzda C stili atamaları kullanmamanızı öneririz çünkü bunlar ile reinterpret_castaynıdır.

Derleyici ve çalışma zamanı örtük atamalar da gerçekleştirir; örneğin, bir değer türü veya yerleşik tür parametre türü Object^olan bir yönteme bağımsız değişken olarak geçirildiğinde kutulama işlemlerinde. Teoride, örtük bir atama hiçbir zaman çalışma zamanında bir özel duruma neden olmamalıdır; derleyici örtük dönüştürme gerçekleştiremiyorsa, derleme zamanında bir hata oluşturur.

Windows Çalışma Zamanı, özel durumlar yerine HRESULT hata kodlarını kullanan COM üzerinden bir soyutlamadır. Genel olarak Platform ::InvalidCastException , E_NOINTERFACE düşük düzeyli com hatasını gösterir.

static_cast

derleme static_cast zamanında denetlenerek iki tür arasında devralma ilişkisi olup olmadığını belirler. Türler ilgili değilse, atama derleyici hatasına neden olur.

Bir başvuru sınıfındaki A static_cast da bir çalışma zamanı denetiminin gerçekleştirilmesine neden olur. Bir başvuru sınıfındaki A static_cast derleme zamanı doğrulamasını geçirebilir, ancak çalışma zamanında yine başarısız olur; bu durumda a Platform::InvalidCastException oluşturulur. Genel olarak, bu özel durumları işlemeniz gerekmez çünkü neredeyse her zaman geliştirme ve test sırasında ortadan kaldırabileceğiniz programlama hatalarını gösterirler.

Kod iki tür arasında açıkça bir ilişki bildiriyorsa ve bu nedenle atamanın çalışması gerektiğine eminseniz kullanın static_cast .

    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

safe_cast işleci Windows Çalışma Zamanı bir parçasıdır. Bir çalışma zamanı türü denetimi gerçekleştirir ve dönüştürme başarısız olursa bir Platform::InvalidCastException oluşturur. Çalışma zamanı hatası olağanüstü bir koşul gösterdiğinde safe_cast kullanın. safe_cast birincil amacı, geliştirme ve test aşamaları sırasında oluşan programlama hatalarını belirlemeye yardımcı olmaktır. İşlenmeyen özel durumun kendisi hata noktasını tanımladığından özel durumu işlemeniz gerekmez.

Kod ilişkiyi bildirmezse ancak atamanın çalışması gerektiğine eminseniz safe_cast kullanın.

    // 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

dynamic_cast Bir nesneyi (daha özel olarak bir şapka^) daha türetilmiş bir türe dönüştürürken kullanın; hedef nesnenin bazen olabileceğini nullptr veya atamanın başarısız olabileceğini ve bu koşulu özel durum yerine normal bir kod yolu olarak işlemek istediğinizi beklersiniz. Örneğin, Boş Uygulama (Evrensel Windows) proje şablonundaki OnLaunched app.xaml.cpp yöntemi, uygulama penceresinde içerik olup olmadığını test etmek için kullanır dynamic_cast . İçeriği yoksa bu bir hata değildir; beklenen bir durumdur. Windows::Current::Content bir Windows::UI::XAML::UIElement ve dönüştürme, devralma hiyerarşisinde daha türetilmiş bir tür olan öğesine Windows::UI.XAML::Controls::Framedönüştürülür.

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();
        // ...
    }
}

başka bir kullanımı dynamic_cast , Object^ kutulu değer türü içerip içermediğini belirlemek için yoklama yapmaktır. Bu durumda, veya dynamic_cast<Platform::Box> dynamic_cast<Platform::IBox>öğesini denersiniz.

dynamic_cast ve izleme başvuruları (%)

ayrıca bir izleme başvurusuna da uygulayabilirsinizdynamic_cast, ancak bu durumda atama safe_cast gibi davranır. Platform::InvalidCastException bir izleme başvurusunun nullptrdeğeri olmadığından hataya neden olur.

reinterpret_cast

Derleme zamanı denetimi veya çalışma zamanı denetimi gerçekleştirilmediği için reinterpret_cast kullanmamanızı öneririz. En kötü durumda, programlama reinterpret_cast hatalarının geliştirme zamanında tespit edilmemesini ve programınızın davranışında küçük veya yıkıcı hatalara neden olmasını mümkün kılar. Bu nedenle, yalnızca ilgisiz türler arasında atamanız gereken ve atamanın başarılı olacağını bildiğiniz nadir durumlarda kullanmanızı reinterpret_cast öneririz. Nadir bir kullanım örneği, bir Windows Çalışma Zamanı türünü temel alınan ABI türüne dönüştürmektir; bu, nesne için başvuru sayımının denetimini aldığınız anlamına gelir. Bunu yapmak için ComPtr Sınıfı akıllı işaretçisini kullanmanızı öneririz. Aksi takdirde, arabirimde Release'ı özellikle çağırmanız gerekir. Aşağıdaki örnek, bir başvuru sınıfının 'a IInspectable*nasıl atanabileceğini gösterir.

#include <wrl.h>
using namespace Microsoft::WRL;
auto winRtObject = ref new SomeWinRTType();
ComPtr<IInspectable> inspectable = reinterpret_cast<IInspectable*>(winRtObject);
// ...

Bir Windows Çalışma Zamanı arabiriminden diğerine dönüştürmek için kullanırsanızreinterpret_cast, nesnenin iki kez serbest bırakılmasına neden olursunuz. Bu nedenle, bu atamayı yalnızca C++ olmayan bileşen uzantıları arabirimine dönüştürürken kullanın.

ABI türleri

  • ABI türleri, Windows SDK'sında üst bilgilerde bulunur. Rahatça, üst bilgiler ad alanlarının adını alır; örneğin, windows.storage.h.

  • ABI türleri özel bir ad alanı ABI'sinde (örneğin, ABI::Windows::Storage::Streams::IBuffer*) bulunur.

  • bir Windows Çalışma Zamanı arabirim türü ile eşdeğer ABI türü arasındaki dönüştürmeler her zaman güvenlidir; yani IBuffer^ öğesine.ABI::IBuffer*

  • Bir Windows Çalışma Zamanı sınıfı, biliniyorsa her zaman veya varsayılan arabirimine dönüştürülmelidirIInspectable*.

  • ABI türlerine dönüştürdükten sonra, türün yaşam süresine sahip olursunuz ve COM kurallarına uymanız gerekir. ABI işaretçilerinin yaşam boyu yönetimini basitleştirmek için kullanmanızı WRL::ComPtr öneririz.

Aşağıdaki tabloda, kullanımı reinterpret_castgüvenli olduğu durumlar özetlemektedir. Her durumda, alçı her iki yönde de güvenlidir.

Atama kimden, atama Şunun için yayın, atama
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^*

Ayrıca bkz.