Classi e struct di valore (C++/CX)
Uno struct valore o una classe valore è un POD compatibile con Windows Runtime ("struttura di dati precedente normale"). con una dimensione fissa e costituita solo da campi; a differenza di una classe di riferimento, non dispone di proprietà.
Gli esempi seguenti mostrano come dichiarare e inizializzare struct di valore.
// 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.";
Quando una variabile di un tipo di valore viene assegnata a un'altra variabile, il valore viene copiato. In tal modo ciascuna delle due variabili dispone di una propria copia dei dati. Uno struct di valore è una struttura di dimensione fissa che contiene solo campi di dati pubblici e viene dichiarata utilizzando la parola chiave value struct
.
Una classe di valore è analoga a uno value struct
, eccetto per il fatto che ai relativi campi deve essere concessa esplicitamente l'accessibilità pubblica. La classe viene dichiarata utilizzando la parola chiave value class
.
Una classe value struct o value può contenere come campi solo tipi numerici fondamentali, classi enumerazioni, Platform::String^
o Platform::IBox <T>^ dove T è un tipo numerico o una classe enum o una classe valore o uno struct. Un campo IBox<T>^
può contenere un valore nullptr
. Ecco come C++ implementa il concetto di tipi di valore nullable.
Uno struct o una classe di valori che contiene un tipo Platform::String^
o IBox<T>^
come membro non supporta memcpy
.
Poiché tutti i membri di una value class
o di uno value struct
sono pubblici e vengono generati nei metadati, i tipi C++ standard non sono consentiti come membri. Non è così per le classi di riferimento che possono contenere tipi C++ standard private
o internal
.
Nel frammento di codice riportato di seguito i tipi Coordinates
e City
vengono dichiarati come struct di valore. Nota che uno dei membri dati City
è un tipo GeoCoordinates
. Uno value struct
può contenere altri struct di valore come membri.
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;
};
Passaggio dei parametri per i tipi valore
Se si ha un tipo valore come parametro di funzione o di metodo, normalmente viene passato per valore. Per gli oggetti di grandi dimensioni, tuttavia, questo può causare un problema di prestazioni. In Visual Studio 2013 e versioni precedenti i tipi valore in C++/CX sono stati sempre passati per valore. In Visual Studio 2015 e versioni successive, è possibile passare i tipi valore per riferimento oppure per valore.
Per dichiarare un parametro che passa un tipo valore per valore, usare codice simile al seguente:
void Method1(MyValueType obj);
Per dichiarare un parametro che passa un tipo valore per riferimento, usa il simbolo di riferimento (&), come illustrato di seguito:
void Method2(MyValueType& obj);
Il tipo in Method2 è un riferimento a MyValueType e funziona esattamente come un tipo di riferimento nel linguaggio C++ standard.
Quando si chiama Method1 da un altro linguaggio, ad esempio C#, non è necessario usare la parola chiave ref
o out
. Quando si chiama Method2, usare la parola chiave ref
.
Method2(ref obj);
Per passare un tipo valore per riferimento è possibile usare anche un simbolo puntatore (*). Il comportamento rispetto ai chiamanti in altri linguaggi è lo stesso (i chiamanti in C# usano la parola chiave ref
), ma nel metodo il tipo è un puntatore al tipo valore.
Tipi valore nullable
Come accennato in precedenza, una classe valore o uno struct valore può avere un campo di tipo Platform::IBox<T>^, IBox<int>^
ad esempio . A tale campo può essere assegnato qualsiasi valore numerico valido per il tipo int
o un valore nullptr
. È possibile passare un campo nullable come argomento a un metodo il cui parametro è dichiarato come facoltativo o qualsiasi altra posizione in cui un tipo di valore non deve necessariamente avere un valore.
L'esempio seguente mostra come inizializzare uno struct con un campo nullable.
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;
}
Uno struct di valori può essere reso nullable in modo analogo, come illustrato di seguito:
public value struct MyStruct
{
public:
int i;
Platform::String^ s;
};
public ref class MyClass sealed
{
public:
property Platform::IBox<MyStruct>^ myNullableStruct;
};
Vedi anche
Sistema di tipi (C++/CX)
Riferimenti al linguaggio C++/CX
Riferimenti a spazi dei nomi
Classi e struct di riferimento (C++/CX)