Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Um value struct ou value class é um POD ("plain old data structure") compatível com o Tempo de Execução do Windows. Tem um tamanho fixo e consiste apenas em campos; ao contrário de uma classe ref, não tem propriedades.
Os exemplos a seguir mostram como declarar e inicializar estruturas de valor.
// 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 uma variável de um tipo de valor é atribuída a outra variável, o valor é copiado, de modo que cada uma das duas variáveis tenha sua própria cópia dos dados. Um valor struct é uma estrutura de tamanho fixo que contém apenas campos de dados públicos e é declarada usando a palavra-chave value struct.
Uma classe de valor é como um value struct exceto que seus campos devem receber explicitamente acessibilidade pública. É declarado usando a palavra-chave value class.
Uma estrutura de valor ou classe de valor pode conter como campos apenas tipos numéricos fundamentais, classes de enumeração, Platform::String^ou Platform::IBox <T>^, onde T é um tipo numérico, classe de enumeração, classe de valor ou estrutura. Um campo IBox<T>^ pode ter um valor de nullptr—é assim que o C++ implementa o conceito de tipos de valor anuláveis.
Uma classe de valor ou estrutura de valor que contém um tipo Platform::String^ ou IBox<T>^ como membro não é memcpy-able.
Como todos os membros de um value class ou value struct são públicos e são emitidos em metadados, os tipos C++ padrão não são permitidos como membros. Isso é diferente das classes ref, que podem conter private ou internal tipos C++ padrão.
O fragmento de código a seguir declara os tipos Coordinates e City como estruturas de valor. Note que um dos membros de dados do City é do tipo GeoCoordinates. Um value struct pode conter outras estruturas de valor como membros.
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;
};
Passagem de parâmetros para tipos de valor
Se você tiver um tipo de valor como um parâmetro de função ou método, ele normalmente é passado por valor. Para objetos maiores, isso pode causar um problema de desempenho. No Visual Studio 2013 e anteriores, os tipos de valor em C++/CX sempre eram passados por valor. No Visual Studio 2015 e posterior, você pode passar tipos de valor por referência ou por valor.
Para declarar um parâmetro que passa um valor tipo por valor, use um código como o seguinte:
void Method1(MyValueType obj);
Para declarar um parâmetro que passa um tipo de valor por referência, use o símbolo de referência (&), como a seguir:
void Method2(MyValueType& obj);
O tipo dentro de Method2 é uma referência a MyValueType e funciona da mesma maneira que um tipo de referência em C++ padrão.
Quando você chama Method1 de outra linguagem, como C#, você não precisa usar o ref ou out palavra-chave. Quando chamar o Method2, use a chave ref.
Method2(ref obj);
Você também pode usar um símbolo de ponteiro (*) para passar um tipo de valor por referência. O comportamento em relação aos chamadores em outros idiomas é o mesmo (chamadores em C# usam a palavra-chave ref), mas no método, o tipo é um ponteiro para o tipo de valor.
Tipos de valor anulável
Como mencionado anteriormente, uma classe de valor ou estrutura de valor pode ter um campo do tipo Platform::IBox<T>^—por exemplo, IBox<int>^. Esse campo pode ter qualquer valor numérico que seja válido para o tipo int ou pode ter um valor de nullptr. Você pode passar um campo anulável como um argumento para um método cujo parâmetro é declarado como opcional ou em qualquer outro lugar em que um tipo de valor não seja necessário para ter um valor.
O exemplo a seguir mostra como inicializar uma struct que tem um campo anulável.
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;
}
Uma estrutura de valor em si pode ser anulável da mesma forma, como mostrado aqui:
public value struct MyStruct
{
public:
int i;
Platform::String^ s;
};
public ref class MyClass sealed
{
public:
property Platform::IBox<MyStruct>^ myNullableStruct;
};
Ver também
Tipo de Sistema (C++/CX)
Referência da linguagem C++/CX
Referência de Namespaces
classes e estruturas Ref (C++/CX)