Clases parciales (C++/CX)
Una clase parcial es una construcción que admite escenarios en los que estás modificando una parte de una definición de clase, y el software que genera código automático, por ejemplo el diseñador XAML, también está modificando código en la misma clase. Mediante el uso de una clase parcial, puedes evitar que el diseñador sobrescriba tu código. En un proyecto de Visual Studio, el modificador partial
se aplica automáticamente al archivo generado.
Sintaxis
Para definir una clase parcial, utiliza la palabra clave partial
inmediatamente delante de la "clase-clave" de lo que de otro modo sería una definición de clase normal. Una palabra clave como partial ref class
es una palabra clave contextual que contiene caracteres de espacio en blanco. Las definiciones parciales se admiten en las siguientes construcciones.
class
ostruct
ref class
oref struct
value class
ovalue struct
enum
oenum class
ref interface
,interface class
,interface struct
o__interface
union
En este ejemplo se muestra una ref class
parcial:
partial ref class MyClass {/* ... */};
Contenido
Una definición de clase parcial puede contener cualquier elemento que la definición de clase completa puede contener si la palabra clave partial
se ha omitido. Con una excepción, esto incluye cualquier construcción válida como clases base, miembros de datos, funciones de miembro, enumeraciones, declaraciones de confianza y atributos. Y se permiten definiciones en línea de miembros de datos estáticos.
La excepción es la accesibilidad de clase. Por ejemplo, la instrucción public partial class MyInvalidClass {/* ... */};
es un error. Los especificadores de acceso que se utilizan en una definición de clase parcial para MyInvalidClass no afectan a la accesibilidad predeterminada en una definición de clase completa o clase parcial subsiguiente para MyInvalidClass.
En el fragmento de código siguiente se muestra la accesibilidad. En la primera clase parcial, Method1
es público porque su accesibilidad es pública. En la segunda clase parcial, Method2
es privado porque la accesibilidad de clase predeterminada es privada.
partial ref class N
{
public:
int Method1(); // Method1 is public.
};
ref class N
{
void Method2(); // Method2 is private.
};
Declaración
Una definición parcial de una clase como MyClass
es solo una declaración de MyClass. Es decir, solo introduce el nombre MyClass
. MyClass
no se puede usar de forma que sea necesaria una definición de clase, por ejemplo, conocer el tamaño de MyClass
o usar una base o un miembro de MyClass
. MyClass
se considera que solo está definido cuando el compilador encuentra una definición no parcial de MyClass
.
En el ejemplo siguiente se muestra el comportamiento de declaración de una clase parcial. Después de declaration #1, se puede utilizar MyClass
como si estuviera escrita como declaración adelantada, ref class MyClass;
. La declaración n.º 2 es equivalente a la declaración n.º 1. La declaración 3 es válida porque es una declaración de reenvío a una clase. Pero Declaration #4 no es válida porque
MyClass
no está totalmente definido.
Declaration #5 no utiliza la palabra clave partial
y la declaración define totalmente MyClass
. Por consiguiente, Declaration #6 es 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 y orden
Puede que haya cero o más definiciones de clase parcial para cada definición completa de una clase.
Cada definición de clase parcial de una clase debe preceder léxicamente a la definición completa de esa clase, pero no tiene que preceder a las declaraciones adelantadas de la clase. Si no hay ninguna definición completa de la clase, las declaraciones de clase parcial solo pueden ser declaraciones adelantadas.
Todas las "clase-claves" como class
y struct
deben coincidir. Por ejemplo, el código siguiente es erróneo: partial class X {}; struct X {};
.
En el ejemplo siguiente se muestra el número y el orden. La última declaración parcial produce un error porque la clase ya 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.
Definición completa
En el punto de la definición completa de la clase X, el comportamiento es el mismo que si la definición de X hubiera declarado todas las clases base, miembros, etc., en el orden en que se encontraron y se definieron en las clases parciales. Es decir, el contenido de las clases parciales se trata como si estuviera escrito en el punto de definición completa de la clase, y la búsqueda de nombre y otras reglas de lenguaje se aplican en el punto de la definición completa de la clase como si el contenido de las clases parciales se hubiera escrito en contexto
Los dos ejemplos de código siguientes tienen idénticos significado y efecto. En el primer ejemplo se utiliza una clase parcial y en el segundo ejemplo no.
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);
};
Templates (Plantillas [C++])
Una clase parcial no puede ser una plantilla.
Restricciones
Una clase parcial no puede abarcar más allá de una unidad de traducción.
La palabra clave partial
solo se admite en combinación con la palabra clave ref class
o la palabra clave value class
.
Ejemplos
En el ejemplo siguiente se define la clase Address
en dos archivos de código. El diseñador modifica Address.details.h
y tú modificas Address.h
. Solo la definición de clase del primer archivo utiliza la palabra clave 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(); }
};
Consulte también
Sistema de tipos
Referencia del lenguaje C++/CX
Referencia de espacios de nombres