PDF de programación - C++/CLI V: Propiedades

Imágen de pdf C++/CLI V: Propiedades

C++/CLI V: Propiedadesgráfica de visualizaciones

Publicado el 28 de Marzo del 2017
1.346 visualizaciones desde el 28 de Marzo del 2017
372,3 KB
7 paginas
Creado hace 16a (16/11/2007)
C++/CLI V: Propiedades

Las propiedades en C++/CLI tienen un tratamiento similar, por no decir idéntico, con su
equivalente en C#, con la diferencia de que son algo más potentes, no porque lo hayan hecho
así, sino por las características notacionales del C++.

El concepto de propiedad no nace con el .NET, sino que existe desde mucho antes. Ya Borland
en su Delphi implementa la idea, luego extendida a C++Builder: la __property.

El concepto nace con la idea de tener una forma de acceder a variables internas de una clase
sin romper el concepto de encapsulación, así como la de permitir realizar efectos laterales en
dichos accesos.

Una propiedad aparentemente representa una variable miembro pública dentro de una clase,
pero realmente oculta en su interior dos llamadas a métodos, una para la lectura y otra para la
escritura. Por ejemplo, el código

int a=unObjeto.Valor;

podría parecer un acceso a una variable pública, pero no lo es cuando hablamos de
propiedades. Y el siguiente código tampoco:

unObjeto.Valor=33;

Aunque a simple vista parezca una lectura y una escritura sobre una variable miembro pública,
realmente se está ejecutando el siguiente código, que el compilador sustituye por nosotros:

int a=unObjeto.get_Valor();

unObjeto.set_Valor(33);

Pero vayamos por partes.

Propiedades triviales
Nunca el nombre estuvo mejor puesto, y aunque C# 3.0 lo traerá, en C++/CLI existe desde el
origen del lenguaje. Una propiedad trivial se declara como:



ref class UnaClase

{



};

public:



property int Valor;

Y se escribe y se lee sobre ella tal y como hemos indicado más arriba. Pero el compilador nos
está engañando (o más bien está haciendo tareas laboriosas en nuestro lugar, lo que siempre
es de agradecer). Lo que realmente está creando es

ref class UnaClase

{



int Valor;

public:



int get_Valor(void){return Valor;}

void set_Valor(int v){Valor=v;}



};

Aunque en nuestro código estemos trabajando como si dichos métodos no existieran,
realmente están en el código compilado, y se llaman de esa misma forma. Es decir, que
podríamos adelantarnos al compilador y crear dichos métodos nosotros mismos a mano, y
entonces podrían ocurrir dos cosas:

 Si ponemos “property Valor;” en la zona pública de la clase, y quitamos la variable de
la zona privada, el compilador entenderá que eso es una propiedad y podremos utilizar
semántica de variable (es decir, como los ejemplos de código de más arriba).

 Si lo dejamos tal y como está, el compilador no entenderá que estamos definiendo una
propiedad y tendremos que utilizar los métodos get_Valor() y set_Valor() como
cualesquiera otros métodos normales.

Esto tiene una contrapartida, y es que si nuestra intención es no crear una propiedad con
dicho nombre, podemos montar un lío de narices, y justo al revés, no querer una propiedad y
montar una, por lo que lo recomendado es no implementar ningún método que empiece por
get_ ni por set_, pero a veces estos ya existen en bibliotecas antiguas, y no podemos evitar su
uso.

Los chicos de Microsoft recomiendan el uso de este tipo de propiedades cuando no tengamos
claro si definir una variable o un método, sobre todo en bibliotecas, ya que así podemos pasar
a implementar “accesores” (por decirlo de alguna manera) de forma transparente sin tener
que modificar el código existente (en general, sin tener que recompilarlo; tan sólo sería
necesario cambiar el ensamblado viejo por el nuevo sin hacer nada más, y otros ensamblados
que accedieran a él no notarían la diferencia, mientras que si seguimos la forma clásica,
también sería necesario recompilar el código que accediera a dicho elemento y no solo el del
propio elemento).

La explicación no tiene misterio. Si definimos una variable pública, el código que acceda a ella
simplemente cargará la dirección de memoria en donde ésta se encuentre (aunque se trate de
una doble indirección como en el caso de las referencias), mientras que si definimos una
propiedad, el código hará una llamada a get_<nombre>() o set_<nombre>(), y si en la
biblioteca hemos cambiado la variable por una propiedad, en el primer caso la aplicación
fallará, en el segundo continuará ejecutándose sin problemas, y nosotros habremos podido
cambiar el comportamiento de la biblioteca al vuelo y sin que nadie se entere.

Propiedades escalares
Estas son las propiedades 100% compatibles con .NET, y de forma equivalente a C#, se
declaran de la misma forma:

ref class UnaClase

{

public:



property int Valor

{



int get(void){return Valor;}

void set(int v){Valor=v;}



}



};

El funcionamiento es idéntico a la forma anterior, con la diferencia de que ahora estamos
declarando los dos métodos que leen y escriben la propiedad, exactamente como en C#. Y
como en C# podemos tener propiedades de sólo
lectura, de sólo escritura y de
lectura/escritura dependiendo de qué métodos implementemos.

Una diferencia importante con C# es que el nombre de los métodos puede ser cualquiera; aquí
nosotros los hemos llamado get y set, pero podríamos haberlos llamado juan y pepe. Lo que sí
debemos tener en cuenta es la firma del método. El de lectura no ha de recibir ningún
parámetro y devolver el mismo tipo que la propiedad y el de escritura justo al revés. Cualquier
otra firma hará que el compilador proteste.

El C++/CLI tiene otra limitación (que creo que también tiene el C#, pero menos visible ya que
parte de lo explicado queda completamente oculto por el compilador). Ya lo hemos dicho con
anterioridad, si una propiedad se llama Valor, no podemos declarar métodos con los nombres
set_Valor() ni get_Valor() ya que el compilador los está generando internamente para
implementar las propiedades.

Lo que sí podemos hacer es declarar en un lado una propiedad e implentarla en otro.
Considerando el código anterior, podríamos definir en el fichero cabecera:

ref class UnaClase

{

public:

property int Valor

{

int get(void);

void set(int v);

}



};

y luego, en el fichero fuente (.cpp), implementar:

int UnaClase::Valor::get(void)

{



}

return Valor;

void UnaClase::Valor::set(int v)

{



}

Valor=v;

Con esta característica damos un paso más allá, permitiendo ver la declaración de la propiedad
pero ocultando el código que la compone en, por ejemplo, una biblioteca. Aunque realmente
esta característica tiene poco valor, ya que mediante reflexión y desensamblado es trivial
conocer el código fuente, pero ahí está para quien quiera usarla.

Acceso, antecesores y otras variantes
Comentar brevemente, antes de entrar en las propiedades indexadas, que las propiedades
pueden ser virtuales, se pueden heredar, ser estáticas, se pueden sobrescribir, pueden tener
diferente tipo de acceso (público, privado, protegido…), e incluso la parte de escritura puede
tener diferente tipo de acceso a la de lectura. Realmente no estamos limitados en nada
respecto a los métodos normales, ya que de hecho las propiedades no son otra cosa que unos
meros alias y forma sincopada de métodos, como hemos podido ver más arriba. Y para
implementarlos sólo debemos poner las palabras reservadas adecuadas en los lugares
adecuados.

De todos modos, el autor no es muy partidario de hacer "florituras" con las propiedades; por
experiencia propia sabe que cuanto más complejo sea un código, más difícil es luego de
depurar y extender. De todos modos podría tener su utilidad justificada. Imaginemos una
biblioteca que expusiera una propiedad de sólo lectura para aquellos elementos que la usen
directamente, y su escritura para aquellos que la heredaran para modificar en alguna manera
su comportamiento. Deberíamos declarar entonces como público el acceso de lectura y como
protegido el de escritura.

Finalmente, cuando surja la duda (que surgirá) sobre qué y cómo operar con las propiedades,
simplemente tenemos que imaginarnos que son métodos sin el paréntesis final, y actuar en
consecuencia.

Propiedades indexadas
Aquí volvemos a salirnos de las características de C#; las propiedades indexadas son aquellas
que se pueden acceder como si fueran un array, es decir:

int a=unObjeto.Valor[índice];

o incluso:

int a=unObjeto[índice];

sin que unObjeto sea un array.

La potencia de todo esto no está en el propio sistema abreviado por corchetes, que es potente
en sí, sino en que el índice puede ser cualquier tipo de dato; es decir, podemos expresar
semánticas todo lo complejas que queramos, quizás sobrepasando el concepto de índice más
allá incluso de la programación genérica, o más bien igualándolo sin toda la parafernalia que la
acompaña.

Es decir, podríamos tener código como este:

Persona ^p=persona["RFOG"];

Casa ^c=casas->CasaDe[p];

En una metonimia para una consulta a una base de datos que obtenga en primer lugar la
persona que viene representada por la cadena "RFOG" y en segundo la casa que pertenece a la

persona indicada. En el primer caso estamos utilizando lo que se conoce como "propiedad
indexada por defecto" y en el segundo "propiedad indexada" a secas.

Evidentemente volvemos a encontrarnos con el tema de la complejidad dentro del código
fuente, ya que dada la potencia del concepto, podemos llegar a realizar asignaciones un tanto
absurdas, así que aquí, igual que antes, el autor recomienda que se utilice esta característica
con cierto rigor y escepticismo.

Pero veamos cómo declarar este tipo de propiedades:

ref class Calendario

{
  • Links de descarga
http://lwp-l.com/pdf2619

Comentarios de: C++/CLI V: Propiedades (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad