Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
C++/CX stöder användardefinierade referensklasser och referensstrukturer samt användardefinierade värdeklasser och värdestrukturer. Dessa datastrukturer är de primära containrar med vilka C++/CX stöder Windows Runtime-typsystemet. Deras innehåll genereras till metadata enligt vissa specifika regler, och detta gör att de kan skickas mellan Windows Runtime-komponenter och Universella Windows Platform-appar som är skrivna på C++ eller andra språk.
En referensklass eller referens struct har följande viktiga funktioner:
Det måste deklareras inom ett namnområde, i namnområdesomfånget, och i det namnområdet kan det ha offentlig eller privat tillgänglighet. Endast offentliga typer genereras till metadata. Kapslade offentliga klassdefinitioner är inte tillåtna, inklusive kapslade offentliga uppräkningsklasser . Mer information finns i Namnområden och Skriv synlighet.
Den kan innehålla som medlemmar C++/CX inklusive referensklasser, värdeklasser, referens structs, värde structs eller nullable value structs. Den kan också innehålla skalära typer som
float64,booloch så vidare. Den kan också innehålla C++-standardtyper, till exempelstd::vectoreller en anpassad klass, så länge de inte är offentliga. C++/CX-konstruktioner kan hapublic,protected,internal,privateellerprotected privatehjälpmedel. Allapublicellerprotectedmedlemmar skickas till metadata. C++-standardtyper måste haprivate,internalellerprotected privatehjälpmedel, vilket förhindrar att de skickas till metadata.Den kan implementera en eller flera gränssnittsklasser eller gränssnittsstrukturer.
Den kan ärva från en basklass och basklasserna själva har ytterligare begränsningar. Arv i offentliga referensklasshierarkier har fler begränsningar än arv i privata referensklasser.
Det får inte deklareras som generiskt. Om den har privat tillgänglighet kan det vara en mall.
Dess livslängd hanteras av automatisk referensräkning.
Deklaration
Följande kodfragment deklarerar referensklassen Person . Observera att C++ std::map -standardtypen används i de privata medlemmarna och att Windows Runtime-gränssnittet IMapView används i det offentliga gränssnittet. Observera också att ^läggs till i deklarationer av referenstyper.
// #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;
};
Genomförande
Det här kodexemplet visar en implementering av referensklassen Person :
#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);
}
Användning
I nästa kodexempel visas hur klientkoden använder referensklassen Person .
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");
Du kan också använda stacksemantik för att deklarera en lokal referensklassvariabel. Ett sådant objekt fungerar som en stackbaserad variabel även om minnet fortfarande allokeras dynamiskt. En viktig skillnad är att du inte kan tilldela en spårningsreferens (%) till en variabel som deklareras med hjälp av stacksemantik. Detta garanterar att referensantalet minskas till noll när funktionen avslutas. Det här exemplet visar en grundläggande referensklass Urioch en funktion som använder den med stacksemantik:
void DoSomething()
{
Windows::Foundation::Uri docs("http://docs.microsoft.com");
Windows::Foundation::Uri^ devCenter = docs.CombineUri("/windows/");
// ...
} // both variables cleaned up here.
Minneshantering
Du allokerar en referensklass i dynamiskt minne med hjälp av nyckelordet ref new .
MyRefClass^ myClass = ref new MyRefClass();
Operatorn ^ handle-to-object kallas för en hatt och är i grunden en smart C++-pekare. Det minne som det pekar på förstörs automatiskt när den sista hatten hamnar utanför omfånget eller uttryckligen är inställt på nullptr.
Per definition har en referensklass referenssemantik. När du tilldelar en referensklassvariabel är det referensen som kopieras, inte själva objektet. I nästa exempel efter tilldelningen pekar både myClass och myClass2 på samma minnesplats.
MyRefClass^ myClass = ref new MyRefClass();
MyRefClass^ myClass2 = myClass;
När en C++/CX ref-klass instansieras initieras dess minne noll innan konstruktorn anropas. Därför är det inte nödvändigt att nollinitiera enskilda medlemmar, inklusive egenskaper. Om klassen C++/CX härleds från en Windows Runtime C++-biblioteksklass (WRL) är endast C++/CX-härledda klassdelen nollinitierad.
Medlemmar
En referensklass kan innehålla public, protectedoch private funktionsmedlemmar, endast public och protected medlemmar genereras till metadata. Kapslade klasser och referensklasser är tillåtna men kan inte vara public. Offentliga fält är inte tillåtna. offentliga datamedlemmar måste deklareras som egenskaper. Privata eller skyddade interna datamedlemmar kan vara fält. Som standard i en referensklass är privatetillgängligheten för alla medlemmar .
En referens-struct är samma som en referensklass, förutom att dess medlemmar som standard har public hjälpmedel.
En public referensklass eller referens struct genereras i metadata, men för att kunna användas från andra Universella Windows Platform-appar och Windows Runtime-komponenter måste den ha minst en offentlig eller skyddad konstruktor. En offentlig referensklass som har en offentlig konstruktor måste också deklareras för sealed att förhindra ytterligare härledning via det binära programgränssnittet (ABI).
Offentliga medlemmar kanske inte deklareras som const eftersom Windows Runtime-typsystemet inte stöder const. Du kan använda en statisk egenskap för att deklarera en offentlig datamedlem med ett konstant värde.
När du definierar en offentlig referensklass eller struct tillämpar kompilatorn de attribut som krävs för klassen och lagrar den informationen i .winmd-filen i appen. Men när du definierar en offentlig oförseglade referensklass tillämpar Windows::Foundation::Metadata::WebHostHidden du attributet manuellt för att säkerställa att klassen inte är synlig för Universella Windows Platform-appar som är skrivna i JavaScript.
En referensklass kan ha C++-standardtyper, inklusive const typer, i alla private, internaleller protected private medlemmar.
Offentliga referensklasser som har typparametrar är inte tillåtna. Användardefinierade allmänna referensklasser är inte tillåtna. En privat, intern eller skyddad privat referensklass kan vara en mall.
Destruktörer
I C++/CX anropar anrop delete på en offentlig destruktor destruktor oavsett objektets referensantal. Med det här beteendet kan du definiera en destructor som utför anpassad rensning av icke-RAII-resurser på ett deterministiskt sätt. Men även i det här fallet tas själva objektet inte bort från minnet. Minnet för objektet frigörs bara när referensantalet når noll.
Om en klasss destructor inte är offentlig anropas den bara när referensantalet når noll. Om du anropar delete ett objekt som har en privat destructor genererar kompilatorn varning C4493, som säger "borttagningsuttrycket har ingen effekt eftersom destruktören av <typnamnet> inte har "offentlig" tillgänglighet."
Ref-klassförstörare kan bara deklareras på följande sätt:
offentliga och virtuella (tillåts på förseglade eller oförseglade typer)
skyddade privata och icke-virtuella (tillåts endast för oförseglade typer)
privata och icke-virtuella (tillåts endast för förseglade typer)
Ingen annan kombination av hjälpmedel, virtualitet och försegladhet tillåts. Om du inte uttryckligen deklarerar en destruator genererar kompilatorn en offentlig virtuell destruator om typens basklass eller någon medlem har en offentlig destruator. Annars genererar kompilatorn en skyddad privat icke-virtuell destructor för oförseglade typer eller en privat icke-virtuell destructor för förseglade typer.
Beteendet är odefinierat om du försöker komma åt medlemmar i en klass som redan har haft sin destructor-körning. det kommer sannolikt att orsaka att programmet kraschar. Att anropa delete t en typ som inte har någon offentlig destrutor har ingen effekt. Att anropa delete this en typ eller basklass som har en känd private eller protected private destructor inifrån sin typhierarki har heller ingen effekt.
När du deklarerar en offentlig destruator genererar kompilatorn koden så att ref-klassen implementerar Platform::IDisposable och destructor implementerar Dispose metoden.
Platform::IDisposable är C++/CX-projektionen av Windows::Foundation::IClosable. Implementera aldrig dessa gränssnitt uttryckligen.
Arv
Plattform::Objektet är den universella basklassen för alla referensklasser. Alla referensklasser kan implicit konverteras till Platform::Object och kan åsidosätta Object::ToString. Windows Runtime-arvsmodellen är dock inte avsedd som en allmän arvsmodell. I C++/CX innebär det att en användardefinierad offentlig referensklass inte kan fungera som en basklass.
Om du skapar en XAML-användarkontroll och objektet deltar i beroendeegenskapssystemet kan du använda Windows::UI::Xaml::DependencyObject som basklass.
När du har definierat en oförseglade klass MyBase som ärver från DependencyObjectkan andra offentliga eller privata referensklasser i komponenten eller appen ärva från MyBase. Arv i offentliga referensklasser bör endast göras för att stödja åsidosättningar av virtuella metoder, polymorf identitet och inkapsling.
En privat bas ref-klass krävs inte för att härleda från en befintlig oförseglade klass. Om du behöver en objekthierarki för att modellera din egen programstruktur eller för att aktivera återanvändning av kod använder du privata eller interna referensklasser, eller ännu bättre, C++-standardklasser. Du kan exponera funktionerna i den privata objekthierarkin via en offentlig förseglad referensklassomslutning.
En referensklass som har en offentlig eller skyddad konstruktor i C++/CX måste deklareras som förseglad. Den här begränsningen innebär att det inte finns något sätt för klasser som är skrivna på andra språk som C# eller Visual Basic att ärva från typer som du deklarerar i en Windows Runtime-komponent som är skriven i C++/CX.
Här är de grundläggande reglerna för arv i C++/CX:
Referensklasser kan ärva direkt från högst en bas ref-klass, men kan implementera valfritt antal gränssnitt.
Om en klass har en offentlig konstruktor måste den deklareras som förseglad för att förhindra ytterligare härledning.
Du kan skapa offentliga oförseglade basklasser som har interna eller skyddade privata konstruktorer, förutsatt att basklassen härleds direkt eller indirekt från en befintlig oförseglat basklass, till exempel
Windows::UI::Xaml::DependencyObject. Arv av användardefinierade referensklasser över .winmd-filer stöds inte. En referensklass kan dock ärva från ett gränssnitt som har definierats i en annan .winmd-fil. Du kan skapa härledda klasser från en användardefinierad bas ref-klass endast inom samma Windows Runtime-komponent eller Universell Windows-plattformsapp.För referensklasser stöds endast offentligt arv.
ref class C{}; public ref class D : private C //Error C3628 {};
I följande exempel visas hur du exponerar en offentlig referensklass som härleds från andra referensklasser i en arvshierarki.
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(){}
//...
};
}
Se även
typsystem
Värdeklasser och structs
C++/CX-språkreferens
referens för namnområden