Value classes and structs (C++/CX)

A value struct or value class is a Windows Runtime-compatible POD ("plain old data structure"). It has a fixed size and consists of fields only; unlike a ref class, it has no properties.

The following examples show how to declare and initialize value structs.

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

When a variable of a value type is assigned to another variable, the value is copied, so that each of the two variables has its own copy of the data. A value struct is a fixed-size structure that contains only public data fields and is declared by using the value struct keyword.

A value class is just like a value struct except that its fields must be explicitly given public accessibility. It's declared by using the value class keyword.

A value struct or value class can contain as fields only fundamental numeric types, enum classes, Platform::String^, or Platform::IBox <T>^ where T is a numeric type or enum class or value class or struct. An IBox<T>^ field can have a value of nullptr—this is how C++ implements the concept of nullable value types.

Because all members of a value class or value struct are public and are emitted into metadata, standard C++ types are not allowed.

A value class or value struct that contains a Platform::String^ or IBox<T>^ type as a member is not memcpy-able.

Because all members of a value class or value struct are public and are emitted into metadata, standard C++ types are not allowed as members. This is different from ref classes, which may contain private or internal standard C++ types..

The following code fragment declares the Coordinates and City types as value structs. Notice that one of the City data members is a GeoCoordinates type. A value struct can contain other value structs as members.

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

As mentioned earlier, a value class or value struct can have a field of type Platform::IBox<T>^—for example, IBox<int>^. Such a field can have any numeric value that is valid for the int type, or it can have a value of nullptr. You can pass a nullable field as an argument to a method whose parameter is declared as optional, or anywhere else that a value type is not required to have a value.

The following example shows how to initialize a struct that has a nullable field.

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

A value struct itself may be made nullable in the same way, as shown here:

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

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