Udostępnij za pośrednictwem


Klasy i struktury wartości (C++/CX)

Struktura wartości lub klasa wartości jest zasobnikem zgodnym z środowisko wykonawcze systemu Windows ("zwykła stara struktura danych"). Ma stały rozmiar i składa się tylko z pól; w przeciwieństwie do klasy ref, nie ma właściwości.

W poniższych przykładach pokazano, jak zadeklarować i zainicjować struktury wartości.

// 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.";

Gdy zmienna typu wartości jest przypisywana do innej zmiennej, wartość jest kopiowana, tak aby każda z tych dwóch zmiennych ma własną kopię danych. Struktura wartości jest strukturą o stałym rozmiarze, która zawiera tylko pola danych publicznych i jest zadeklarowana przy użyciu słowa kluczowego value struct .

Klasa wartości jest podobnie jak klasa, z tą różnicąvalue struct, że jej pola muszą być jawnie podane publiczne ułatwienia dostępu. Jest zadeklarowany przy użyciu słowa kluczowego value class .

Struktura wartości lub klasa wartości może zawierać jako pola tylko podstawowe typy liczbowe, klasy Platform::String^wyliczenia, lub Platform::IBox <T^, gdzie T> jest typem liczbowym, klasą wyliczeniową lub klasą wartości lub strukturą. Pole IBox<T>^ może mieć wartość nullptr— w ten sposób język C++ implementuje koncepcję typów wartości dopuszczanych do wartości null.

Klasa wartości lub struktura wartości, która zawiera Platform::String^ typ lub IBox<T>^ jako element członkowski, nie memcpyjest w stanie.

Ponieważ wszystkie elementy członkowskie elementu value class lub value struct są publiczne i są emitowane do metadanych, standardowe typy języka C++ nie są dozwolone jako elementy członkowskie. Różni się to od klas ref, które mogą zawierać private lub internal standardowe typy języka C++.

Poniższy fragment kodu deklaruje Coordinates typy i City jako struktury wartości. Zwróć uwagę, że jeden z City elementów członkowskich danych jest typem GeoCoordinates . Element value struct może zawierać inne struktury wartości jako elementy członkowskie.

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;
};

Przekazywanie parametrów dla typów wartości

Jeśli masz typ wartości jako parametr funkcji lub metody, jest on zwykle przekazywany przez wartość. W przypadku większych obiektów może to spowodować problem z wydajnością. W programie Visual Studio 2013 i starszych typy wartości w języku C++/CX były zawsze przekazywane przez wartość. W programie Visual Studio 2015 lub nowszym można przekazać typy wartości według odwołania lub wartości.

Aby zadeklarować parametr przekazujący typ wartości według wartości, użyj kodu podobnego do następującego:

void Method1(MyValueType obj);

Aby zadeklarować parametr przekazujący typ wartości według odwołania, użyj symbolu odwołania (&), jak pokazano poniżej:

void Method2(MyValueType& obj);

Typ wewnątrz metody Method2 jest odwołaniem do MyValueType i działa tak samo jak typ odwołania w standardowym języku C++.

Podczas wywoływania metody Method1 z innego języka, takiego jak C#, nie trzeba używać słowa kluczowego ref lub out . Podczas wywoływania metody Method2 użyj słowa kluczowego ref .

Method2(ref obj);

Możesz również użyć symbolu wskaźnika (*), aby przekazać typ wartości według odwołania. Zachowanie w odniesieniu do wywołań w innych językach jest takie samo (osoby wywołujące w języku C# używają ref słowa kluczowego), ale w metodzie typ jest wskaźnikiem do typu wartości.

Typy wartości dopuszczające wartość null

Jak wspomniano wcześniej, klasa wartości lub struktura wartości może mieć pole typu Platform::IBox<T>^— na przykład IBox<int>^. Takie pole może mieć dowolną wartość liczbową prawidłową dla int typu lub może mieć wartość nullptr. Pole dopuszczające wartość null można przekazać jako argument do metody, której parametr jest zadeklarowany jako opcjonalny lub gdziekolwiek indziej, że typ wartości nie jest wymagany do posiadania wartości.

W poniższym przykładzie pokazano, jak zainicjować strukturę, która ma pole dopuszczające wartość null.

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;
}

Sama struktura wartości może być równa null w taki sam sposób, jak pokazano poniżej:

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

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

Zobacz też

System typów (C++/CX)
Dokumentacja języka C++/CX
Dokumentacja przestrzeni nazw
Klasy i struktury odwołania (C++/CX)