Dela via


Värdeklasser och structs (C++/CX)

En värdestruktur eller värdeklass är en Windows Runtime-kompatibel POD ("vanlig gammal datastruktur"). Den har en fast storlek och består endast av fält. till skillnad från en referensklass har den inga egenskaper.

I följande exempel visas hur du deklarerar och initierar värdestrukturer.

// in mainpage.xaml.h:
    value struct TestStruct
    {
        Platform::String^ str;
        int i;
    };

    value struct TestStruct2
    {
        TestStruct ts;
        Platform::String^ str;
        int i;
    };

// in mainpage.cpp:
    // Initialize a value struct with an int and String
    TestStruct ts = {"I am a TestStruct", 1};

    // Initialize a value struct that contains
    // another value struct, an int and a String
    TestStruct2 ts2 = {{"I am a TestStruct", 1}, "I am a TestStruct2", 2};

    // Initialize value struct members individually.
    TestStruct ts3;
    ts3.i = 108;
    ts3.str = "Another way to init a value struct.";

När en variabel av en värdetyp tilldelas till en annan variabel kopieras värdet så att var och en av de två variablerna har en egen kopia av data. En värdestruktur är en struktur med fast storlek som endast innehåller offentliga datafält och som deklareras med hjälp av nyckelordet value struct.

En värdeklass är precis som en value struct förutom att dess fält uttryckligen måste ges offentlig tillgänglighet. Det deklareras med hjälp av nyckelordet value class.

En värde struct- eller värdeklass kan endast innehålla som fält grundläggande numeriska typer, uppräkningsklasser, Platform::String^eller Plattform::IBox <T>^ där T är en numerisk typ eller uppräkningsklass eller värdeklass eller struct. Ett IBox<T>^ fält kan ha värdet nullptr– det är så C++ implementerar begreppet null-värdetyper.

En värdeklass eller värdestruktur som innehåller en Platform::String^- eller IBox<T>^-typ som medlem är inte memcpy-kompatibel.

Eftersom alla medlemmar i en value class eller value struct är offentliga och genereras till metadata tillåts inte C++-standardtyper som medlemmar. Detta skiljer sig från referensklasser som kan innehålla private eller internal C++-standardtyper.

Följande kodfragment deklarerar Coordinates och City typer som värdestrukturer. Observera att en av City:s datamedlemmar är av typen GeoCoordinates. En value struct kan innehålla andra värdestrukturer som medlemmar.

public enum class Continent 
{  
    Africa,
    Asia,
    Australia,
    Europe,
    NorthAmerica,
    SouthAmerica,
    Antarctica 
};

value struct GeoCoordinates
{
    double Latitude; //or float64 if you prefer
    double Longitude;
};

value struct City
{
    Platform::String^ Name;
    int Population;
    double AverageTemperature;
    GeoCoordinates Coordinates;
    Continent continent;
};

Överföring av parametrar för värdetyper

Om du har en värdetyp som en funktions- eller metodparameter, skickas den normalt som värde. För större objekt kan detta orsaka prestandaproblem. I Visual Studio 2013 och tidigare skickades alltid värdetyper i C++/CX som värde. I Visual Studio 2015 och senare kan du skicka värdetyper efter referens eller värde.

Om du vill deklarera en parameter som tar emot en värdetyp som värde använder du kod som följande:

void Method1(MyValueType obj);

Om du vill deklarera en parameter som skickar en värdetyp efter referens använder du referenssymbolen (&), som i följande:

void Method2(MyValueType& obj);

Typen inuti Method2 är en referens till MyValueType och fungerar på samma sätt som en referenstyp i standard-C++.

När du anropar Method1 från ett annat språk, till exempel C#, behöver du inte använda nyckelordet ref eller out. När du anropar Method2 använder du nyckelordet ref.

Method2(ref obj);

Du kan också använda en pekarsymbol (*) för att skicka en värdetyp via referens. Beteendet för anropare på andra språk är detsamma (anropare i C# använder nyckelordet ref), men i metoden är typen en pekare till värdetypen.

Typer av null-värden

Som tidigare nämnts kan en värdeklass eller värde struct ha ett fält av typen Platform::IBox<T>^– till exempel IBox<int>^. Ett sådant fält kan ha valfritt numeriskt värde som är giltigt för den int typen, eller så kan det ha värdet nullptr. Du kan skicka ett null-fält som ett argument till en metod vars parameter har deklarerats som valfri, eller någon annanstans där en värdetyp inte krävs för att ha ett värde.

I följande exempel visas hur du initierar en struct som har ett null-fält.

public value struct Student
{
    Platform::String^ Name;
    int EnrollmentYear;
    Platform::IBox<int>^ GraduationYear; // Null if not yet graduated.
};
//To create a Student struct, one must populate the nullable type.
MainPage::MainPage()
{
    InitializeComponent();

    Student A;
    A.Name = "Alice";
    A.EnrollmentYear = 2008;
    A.GraduationYear = ref new Platform::Box<int>(2012);

    Student B;
    B.Name = "Bob";
    B.EnrollmentYear = 2011;
    B.GraduationYear = nullptr;

    IsCurrentlyEnrolled(A);
    IsCurrentlyEnrolled(B);
}
bool MainPage::IsCurrentlyEnrolled(Student s)
{
    if (s.GraduationYear == nullptr)
    {
        return true;
    }
    return false;
}

En värdestruct kan göras nullbar på samma sätt, som visas här.

public value struct MyStruct
{
public:
    int i;
    Platform::String^ s;
};

public ref class MyClass sealed
{
public:
    property Platform::IBox<MyStruct>^ myNullableStruct;
};

Se även

Typsystem (C++/CX)
C++/CX-språkreferens
referens för namnområden
Referensklasser och strukturer (C++/CX)