Başvuru Sınıfları ve Yapıları (C++/CX)

C++/CX, kullanıcı tanımlı başvuru sınıflarını ve başvuru yapılarını, kullanıcı tanımlı değer sınıflarını ve değer yapılarını destekler. Bu veri yapıları, C++/CX'in Windows Çalışma Zamanı tür sistemini desteklediği birincil kapsayıcılardır. İçerikleri belirli kurallara göre meta verilere yayılır ve bu sayede C++ veya diğer dillerde yazılmış Windows Çalışma Zamanı bileşenleri ile Evrensel Windows Platformu uygulamaları arasında geçirilebilir.

Bir başvuru sınıfı veya başvuru yapısı şu temel özelliklere sahiptir:

  • Ad alanı içinde, ad alanı kapsamında bildirilmelidir ve bu ad alanında genel veya özel erişilebilirliği olabilir. Meta verilerde yalnızca genel türler yayılır. İç içe genel sabit listesi sınıfları da dahil olmak üzere iç içe genel sınıf tanımlarına izin verilmez. Daha fazla bilgi için bkz . Ad Alanları ve Tür Görünürlüğü.

  • Başvuru sınıfları, değer sınıfları, başvuru yapıları, değer yapıları veya null atanabilir değer yapıları dahil olmak üzere C++/CX üyeleri olarak içerebilir. Ayrıca, , boolvb. gibi float64skaler türler de içerebilir. Genel olmayan veya özel bir sınıf gibi std::vector standart C++ türleri de içerebilir. C++/CX yapılarında , protected, internal, privateveya protected private erişilebilirliği olabilirpublic. Tüm public veya protected üyeler meta veriye yayılır. Standart C++ türlerinin privatemeta veriye gönderilmesini engelleyen , internalveya protected private erişilebilirliği olmalıdır.

  • Bir veya daha fazla arabirim sınıfı veya arabirim yapısı uygulayabilir.

  • Bir temel sınıftan devralabilir ve temel sınıfların kendileri ek kısıtlamalara sahiptir. Genel başvuru sınıfı hiyerarşilerindeki devralma, özel başvuru sınıflarındaki devralmadan daha fazla kısıtlamaya sahiptir.

  • Genel olarak bildirilmeyebilir. Özel erişilebilirliği varsa bir şablon olabilir.

  • Yaşam süresi otomatik başvuru sayımıyla yönetilir.

Bildirim

Aşağıdaki kod parçası ref sınıfını Person bildirir. Standart C++ std::map türünün özel üyelerde ve Windows Çalışma Zamanı IMapView arabiriminin ortak arabirimde kullanıldığına dikkat edin. Ayrıca başvuru türlerinin bildirimlerine "^" eklendiğine de dikkat edin.

// #include <map>
namespace WFC = Windows::Foundation::Collections;
namespace WFM = Windows::Foundation::Metadata;

[WFM::WebHostHidden]
ref class Person sealed
{
public:
    Person(Platform::String^ name);
    void AddPhoneNumber(Platform::String^ type, Platform::String^ number);
    property WFC::IMapView<Platform::String^, Platform::String^>^ PhoneNumbers
    { 
        WFC::IMapView<Platform::String^, Platform::String^>^ get();
    }
private:
    Platform::String^ m_name;
    std::map<Platform::String^, Platform::String^> m_numbers;
};

Uygulama

Bu kod örneği, ref sınıfının bir uygulamasını Person gösterir:

#include <collection.h>
using namespace Windows::Foundation::Collections;
using namespace Platform;
using namespace Platform::Collections;

Person::Person(String^ name): m_name(name) { }
void Person::AddPhoneNumber(String^ type, String^ number)
{
    m_numbers[type] = number;
}
IMapView< String^, String^>^ Person::PhoneNumbers::get()
{
    // Simple implementation. 
    return ref new MapView< String^, String^>(m_numbers);
}

Kullanım

Sonraki kod örneği, istemci kodunun ref sınıfını Person nasıl kullandığını gösterir.

using namespace Platform;

Person^ p = ref new Person("Clark Kent");
p->AddPhoneNumber("Home", "425-555-4567");
p->AddPhoneNumber("Work", "206-555-9999");
String^ workphone = p->PhoneNumbers->Lookup("Work");

Yerel bir başvuru sınıfı değişkeni bildirmek için yığın semantiğini de kullanabilirsiniz. Böyle bir nesne, bellek hala dinamik olarak ayrılmış olsa bile yığın tabanlı değişken gibi davranır. Önemli farklardan biri, yığın semantiği kullanılarak bildirilen bir değişkene izleme başvurusu (%) atayamamanızdır; bu, işlevden çıkıldığında başvuru sayısının sıfıra inmesi garanti eder. Bu örnekte temel bir başv sınıfı Urive bunu yığın semantiğiyle kullanan bir işlev gösterilmektedir:

void DoSomething()
{
    Windows::Foundation::Uri docs("http://docs.microsoft.com");
    Windows::Foundation::Uri^ devCenter = docs.CombineUri("/windows/");
    // ... 
} // both variables cleaned up here.

Bellek yönetimi

Anahtar sözcüğünü kullanarak ref new dinamik bellekte bir ref sınıfı ayırırsınız.

MyRefClass^ myClass = ref new MyRefClass();

Tanıtıcıdan nesneye işleci ^ şapka olarak bilinir ve temelde bir C++ akıllı işaretçisidir. son şapka kapsamın dışına çıktığında veya açıkça olarak olarak ayarlandığında nullptrişaret eden bellek otomatik olarak yok edilir.

Tanım gereği ref sınıfı başvuru semantiğine sahiptir. Bir başvuru sınıfı değişkeni atadığınızda, nesnenin kendisi değil kopyalanan tanıtıcıdır. Sonraki örnekte, atamadan sonra hem hem de myClassmyClass2 aynı bellek konumuna işaret edin.

MyRefClass^ myClass = ref new MyRefClass();
MyRefClass^ myClass2 = myClass;

C++/CX başvuru sınıfı örneği başlatıldığında, oluşturucu çağrılmadan önce belleği sıfır başlatılır; bu nedenle, özellikler de dahil olmak üzere tek tek üyeleri sıfırdan başlatmak gerekli değildir. C++/CX sınıfı bir Windows Çalışma Zamanı C++ Kitaplığı (WRL) sınıfından türetiliyorsa, yalnızca C++/CX türetilmiş sınıf bölümü sıfır başlatılır.

Üyeler

Bir başvuru sınıfı , protectedve işlev üyelerini içerebilirpublic; yalnızca public ve protected üyeler meta veriye private yayılır. İç içe sınıflara ve başvuru sınıflara izin verilir, ancak olamaz public. Ortak alanlara izin verilmez; genel veri üyeleri özellik olarak bildirilmelidir. Özel veya korumalı iç veri üyeleri alanlar olabilir. Ref sınıfında varsayılan olarak tüm üyelerin erişilebilirliği olur private.

Bir başvuru yapısı, varsayılan olarak üyelerinin public erişilebilirliği olması dışında bir başvuru sınıfıyla aynıdır.

Başvuru public sınıfı veya başvuru yapısı meta verilerde yayılır, ancak diğer Evrensel Windows Platformu uygulamalarından ve Windows Çalışma Zamanı bileşenlerinden kullanılabilir olması için en az bir ortak veya korumalı oluşturucuya sahip olması gerekir. Uygulama ikili arabirimi (ABI) aracılığıyla daha fazla türetilmesini önlemek için ortak oluşturucuya sahip bir genel başvuru sınıfı da olarak sealed bildirilmelidir.

Windows Çalışma Zamanı türü sistemi sabiti desteklemediğinden genel üyeler olarak const bildirilmeyebilir. Sabit değere sahip bir genel veri üyesini bildirmek için statik bir özellik kullanabilirsiniz.

Bir genel başvuru sınıfı veya yapısı tanımladığınızda, derleyici gerekli öznitelikleri sınıfına uygular ve bu bilgileri uygulamanın .winmd dosyasında depolar. Ancak, genel korumasız bir başvuru sınıfı tanımladığınızda, sınıfın Windows::Foundation::Metadata::WebHostHidden JavaScript'te yazılmış Evrensel Windows Platformu uygulamalara görünmediğinden emin olmak için özniteliğini el ile uygulayın.

Başvuru sınıfı, herhangi bir private, internalveya protected private üyedeki türler de dahil olmak üzere const standart C++ türlerine sahip olabilir.

Tür parametrelerine sahip genel başvuru sınıflarına izin verilmez. Kullanıcı tanımlı genel başvuru sınıflara izin verilmez. Özel, iç veya korumalı özel başvuru sınıfı bir şablon olabilir.

Yıkıcılar

C++/CX'te, genel bir yıkıcıda çağrılması delete , nesnenin başvuru sayısına bakılmaksızın yok ediciyi çağırır. Bu davranış, RAII olmayan kaynakların belirleyici bir şekilde özel temizlemesini gerçekleştiren bir yıkıcı tanımlamanızı sağlar. Ancak, bu durumda bile nesnenin kendisi bellekten silinmez. Nesnenin belleği yalnızca başvuru sayısı sıfıra ulaştığında serbesttir.

Bir sınıfın yıkıcısı genel değilse, yalnızca başvuru sayısı sıfıra ulaştığında çağrılır. Özel bir yıkıcısı olan bir nesneyi çağırırsanızdelete, derleyici C4493 uyarısını oluşturur ve "tür adının> yıkıcısının 'genel' erişilebilirliği olmadığından silme ifadesinin <hiçbir etkisi yoktur."

Başvuru sınıfı yıkıcıları yalnızca aşağıdaki gibi bildirilebilir:

  • genel ve sanal (korumalı veya korumasız türlerde izin verilir)

  • korumalı özel ve sanal olmayan (yalnızca korumasız türlerde izin verilir)

  • özel ve sanal olmayan (yalnızca korumalı türlerde izin verilir)

Başka erişilebilirlik, sanallık ve korumalılık birleşimine izin verilmez. Bir yıkıcıyı açıkça bildirmezseniz, türün temel sınıfı veya herhangi bir üyenin ortak bir yıkıcısı varsa, derleyici bir genel sanal yıkıcı oluşturur. Aksi takdirde, derleyici korumasız türler için korumalı bir özel sanal olmayan yıkıcı veya korumalı türler için özel bir sanal olmayan yıkıcı oluşturur.

Zaten yok edici çalıştırması olan bir sınıfın üyelerine erişmeye çalışırsanız davranış tanımlanmamıştır; büyük olasılıkla programın kilitlenmesine neden olur. Genel yıkıcısı olmayan bir tür üzerinde çağrılmasının delete t hiçbir etkisi yoktur. Tür hiyerarşisinden bilinen private veya yıkıcısı olan bir tür veya protected private temel sınıf üzerinde çağrılmasının delete this da hiçbir etkisi yoktur.

Bir genel yıkıcı bildirdiğinizde, derleyici kodu oluşturur, böylece ref sınıfı uygular Platform::IDisposable ve yıkıcı yöntemini uygular Dispose . Platform::IDisposable , C++/CX projeksiyonudur Windows::Foundation::IClosable. Bu arabirimleri hiçbir zaman açıkça uygulamayın.

Devralma

Platform::Object, tüm başvuru sınıfları için evrensel temel sınıftır. Tüm başvuru sınıfları örtük olarak Platform::Object olarak dönüştürülebilir ve Object::ToString'i geçersiz kılabilir. Ancak, Windows Çalışma Zamanı devralma modeli genel devralma modeli olarak tasarlanmamıştır; C++/CX'te bu, kullanıcı tanımlı bir ortak başvuru sınıfının temel sınıf olarak hizmet veremeyeceği anlamına gelir.

Bir XAML kullanıcı denetimi oluşturuyorsanız ve nesnesi bağımlılık özellik sistemine katılıyorsa, temel sınıf olarak kullanabilirsiniz Windows::UI::Xaml::DependencyObject .

öğesinden DependencyObjectdevralan korumasız bir sınıf MyBase tanımladıktan sonra, bileşeninizdeki veya uygulamanızdaki diğer genel veya özel başvuru sınıfları öğesinden MyBasedevralabilir. Genel başvuru sınıflarında devralma yalnızca sanal yöntemlerin, çok biçimli kimliğin ve kapsüllemenin geçersiz kılınmalarını desteklemek için yapılmalıdır.

Mevcut korumasız bir sınıftan türetmek için özel bir temel başvuru sınıfı gerekli değildir. Kendi program yapınızı modellemek veya kodu yeniden kullanmayı etkinleştirmek için bir nesne hiyerarşisine ihtiyacınız varsa, özel veya iç başvuru sınıflarını ya da daha iyisi standart C++ sınıflarını kullanın. Özel nesne hiyerarşisinin işlevselliğini genel korumalı bir başvuru sınıfı sarmalayıcı aracılığıyla kullanıma açabilirsiniz.

C++/CX'te ortak veya korumalı oluşturucuya sahip bir başvuru sınıfı korumalı olarak bildirilmelidir. Bu kısıtlama, C# veya Visual Basic gibi başka dillerde yazılmış sınıfların, C++/CX ile yazılmış bir Windows Çalışma Zamanı bileşeninde bildirdiğiniz türlerden devralınması için hiçbir yol olmadığı anlamına gelir.

C++/CX'te devralmayla ilgili temel kurallar şunlardır:

  • Başvuru sınıfları doğrudan en fazla bir temel başvuru sınıfından devralabilir, ancak istediğiniz sayıda arabirim uygulayabilir.

  • Bir sınıfın bir ortak oluşturucu varsa, daha fazla türetme önlemek için korumalı olarak bildirilmelidir.

  • Temel sınıfın gibi Windows::UI::Xaml::DependencyObjectmevcut korumasız bir temel sınıftan doğrudan veya dolaylı olarak türetmesi koşuluyla, iç veya korumalı özel oluşturucuları olan genel korumasız temel sınıflar oluşturabilirsiniz. .winmd dosyaları arasında kullanıcı tanımlı başvuru sınıflarının devralınması desteklenmez; ancak ref sınıfı, başka bir .winmd dosyasında tanımlanan bir arabirimden devralabilir. Kullanıcı tanımlı temel başvuru sınıfından türetilmiş sınıfları yalnızca aynı Windows Çalışma Zamanı bileşeni veya Evrensel Windows Platformu uygulaması içinde oluşturabilirsiniz.

  • Başvuru sınıfları için yalnızca genel devralma desteklenir.

    ref class C{};
    public ref class D : private C //Error C3628
    {};
    

Aşağıdaki örnekte, devralma hiyerarşisindeki diğer başvuru sınıflarından türetilen bir genel ref sınıfının nasıl kullanıma sunulur olduğu gösterilmektedir.

namespace InheritanceTest2 
{
    namespace WFM = Windows::Foundation::Metadata;

    // Base class. No public constructor.
    [WFM::WebHostHidden]
    public ref class Base : Windows::UI::Xaml::DependencyObject
    {
    internal:
        Base(){}
    protected:
        virtual void DoSomething (){}
        property Windows::UI::Xaml::DependencyProperty^ WidthProperty;
    };

    // Class intended for use by client code across ABI.
    // Declared as sealed with public constructor.
    public ref class MyPublicClass sealed : Base
    {
    public:
        MyPublicClass(){}
        //...
    };
}

Ayrıca bkz.

Tür Sistemi
Değer sınıfları ve yapıları
C++/CX Dil Başvurusu
Ad Alanları Başvurusu