Classes parciais (C++/CX)
Uma classe parcial é uma construção que oferece suporte a cenários nos quais você está modificando uma parte da definição de uma classe e software de geração de código automático, por exemplo, o designer XAML, também está modificando código na mesma classe. Usando uma classe parcial, você pode impedir que o designer substitua o seu código. Em um projeto do Visual Studio, o modificador de partial
é aplicado automaticamente ao arquivo gerado.
Sintaxe
Para definir uma classe parcial, use a palavra-chave partial
imediatamente antes da chave de classe do que de outra forma seria uma definição de classe normal. Uma palavra-chave como partial ref class
é uma palavra-chave contextual que contém caracteres de espaço em branco. As construções a seguir oferecem suporte para as definições parciais.
class
oustruct
ref class
ouref struct
value class
ouvalue struct
enum
ouenum class
ref interface
,interface class
,interface struct
ou__interface
union
Este exemplo demonstra uma ref class
parcial:
partial ref class MyClass {/* ... */};
Sumário
Uma definição de classe parcial poderá conter tudo que a definição de classe completa pode conter se a palavra-chave partial
tiver sido omitida. Com uma exceção, isso inclui qualquer construção válida, como classes base, membros de dados, funções de membro, enums, declarações amigáveis e atributos. E definições embutidas de membros de dados estáticos são permitidas.
A única exceção é a acessibilidade da classe. Por exemplo, a declaração public partial class MyInvalidClass {/* ... */};
é um erro. Os especificadores de acesso usados em uma definição de classe parcial para MyInvalidClass não afetam a acessibilidade padrão em uma definição de classe parcial ou completa para MyInvalidClass.
O fragmento de código a seguir demonstra a acessibilidade. Na primeira classe parcial, Method1
é público porque sua acessibilidade é pública. Na segunda classe parcial, Method2
é particular porque a acessibilidade de classe padrão é particular.
partial ref class N
{
public:
int Method1(); // Method1 is public.
};
ref class N
{
void Method2(); // Method2 is private.
};
Declaração
Uma definição parcial de uma classe como MyClass
é apenas uma declaração de MyClass. Isto é, apresenta somente o nome MyClass
. MyClass
não pode ser usada de maneira que exija uma definição de classe, por exemplo, sabendo o tamanho de MyClass
ou usando uma base ou um membro de MyClass
. MyClass
é considerada para definição somente quando o compilador encontra uma definição não parcial de MyClass
.
O exemplo a seguir demonstra o comportamento da declaração de uma classe parcial. Após a declaração #1, MyClass
poderá ser usado como se tivesse sido escrito como a declaração de encaminhamento ref class MyClass;
. A declaração #2 é equivalente à declaração #1. A declaração #3 é válida porque é uma declaração de encaminhamento para uma classe. Mas a declaração 4 não é válida porque
MyClass
não está totalmente definido.
A declaração #5 não usa a palavra-chave partial
e a declaração define totalmente MyClass
. Portanto, a declaração 6 é válida.
// Declaration #1
partial ref class MyClass {};
// Declaration #2
partial ref class MyClass;
// Declaration #3
MyClass^ pMc; // OK, forward declaration.
// Declaration #4
MyClass mc; // Error, MyClass is not defined.
// Declaration #5
ref class MyClass { };
// Declaration #6
MyClass mc; // OK, now MyClass is defined.
Número e ordenação
Pode haver definições de classe zero ou mais parciais para cada definição completa de uma classe.
Cada definição parcial de uma classe deve preceder lexicalmente a única definição completa de uma classe, mas não tem de preceder declarações de encaminhamento da classe. Se não houver nenhuma definição completa da classe, as declarações parciais da classe somente poderão ser declarações de encaminhamento.
Todas as chaves de classe, como class
e struct
, devem coincidir. Por exemplo, é incorreto codificar partial class X {}; struct X {};
.
O exemplo a seguir demonstra o número e a ordenação. A última declaração parcial falha porque a classe já está definida.
ref class MyClass; // OK
partial ref class MyClass{}; //OK
partial ref class MyClass{}; // OK
partial ref class MyClass{}; // OK
ref class MyClass{}; // OK
partial ref class MyClass{}; // C3971, partial definition cannot appear after full definition.
Definição completa
No ponto da definição completa da classe X, o comportamento será igual como se a definição de X tivesse declarado todas as classes base, membros etc. na ordem em que foram encontrados e definidos nas classes parciais. Ou seja, o conteúdo das classes parciais é tratado como se elas tivessem sido escritas no ponto da definição completa da classe e outras regras de pesquisa de nome e linguagem fossem aplicadas no ponto da definição completa da classe, como se o conteúdo das classes parciais fosse escrito no lugar
Os dois exemplos de código a seguir têm significado e o efeito idênticos. O primeiro exemplo usa uma classe parcial e o segundo exemplo não.
ref class Base1 { public: property int m_num; int GetNumBase();};
interface class Base2 { int GetNum(); };
interface class Base3{ int GetNum2();};
partial ref class N : public Base1
{
public:
/*...*/
};
partial ref class N : public Base2
{
public:
virtual int GetNum();
// OK, as long as OtherClass is
//declared before the full definition of N
void Method2( OtherClass^ oc );
};
ref class OtherClass;
ref class N : public Base3
{
public:
virtual int GetNum2();
};
ref class OtherClass;
ref class N : public Base1, public Base2, public Base3
{
public:
virtual int GetNum();
virtual int GetNum2();
private:
void Method2(OtherClass^ oc);
};
Modelos
Uma classe parcial não pode ser um modelo.
Restrições
Uma classe parcial não pode se estender além de uma unidade de conversão.
A palavra-chave partial
tem suporte apenas em combinação com a palavra-chave ref class
ou a palavra-chave value class
.
Exemplos
O exemplo a seguir define a classe Address
em dois arquivos de código. O designer modifica Address.details.h
e você modifica Address.h
. Somente a definição de classe no primeiro arquivo usa a palavra-chave partial
.
// Address.Details.h
partial ref class Address
{
private:
Platform::String^ street_;
Platform::String^ city_;
Platform::String^ state_;
Platform::String^ zip_;
Platform::String^ country_;
void ValidateAddress(bool normalize = true);
};
// Address.h
#include "Address.details.h"
ref class Address
{
public:
Address(Platform::String^ street, Platform::String^ city, Platform::String^ state,
Platform::String^ zip, Platform::String^ country);
property Platform::String^ Street { Platform::String^ get(); }
property Platform::String^ City { Platform::String^ get(); }
property Platform::String^ State { Platform::String^ get(); }
property Platform::String^ Zip { Platform::String^ get(); }
property Platform::String^ Country { Platform::String^ get(); }
};
Confira também
Sistema de tipos
Referência da linguagem C++/CX
Referência de namespaces