C++/CX (IV). Clases parciales

Éramos pocos y parió la abuela. ¿Sabéis por qué C++/CLI (el C++ de .NET) se quedó en la cuneta en eso de ser a first class .NET language (o en cristiano: un lenguaje .NET de primera clase)? Efectivamente, la ausencia de clases parciales.

Cuando Microsoft introdujo el .NET 3.0 también cambió la forma de entender la interacción con la parte visual. Si bien antes las ventanas se construían con código, aunque de forma más o menos automatizada gracias al diseñador visual (hablamos de Windows Forms), a partir de ese momento se implementó una nueva forma que, pese a ser una idea cojonuda, peca un poco de mal implementada, como casi todo lo que hace la casa.

Los viejos lobos de mar nos hemos defendido con las plantillas de cuadro de diálogo, que definían los tales mediante una serie de palabras claves. Luego Windows se encargaba de leer la versión binaria de ese texto y nos construía nuestro cuadro de diálogo.

Pues bien, XAML es la enésima reencarnación de lo mismo, pero con esteroides. Y digo enésima porque por ejemplo Delphi, C++ Builder e incluso el ya vetusto VB6 lo hacían más o menos así.

XAML es un lenguaje (lo que me cuesta llamarlo así) XML que define la estructura de una ventana y todos sus componentes. La idea es tener algo que nos defina por completo, y de forma independiente del código, la parte visual de un programa y que encima se pueda crear tanto de forma manual como con programas… Eso sí, léete tu un fichero XAML escrito con Blend, que lo vas a flipar en colores.

Bueno, a lo que vamos, XAML tiene que poder interactuar de alguna forma con el código. Para evitarnos cosas como MFC, Microsoft permitió que se pudiera definir una misma clase en más de un fichero. Y nacieron las clase parciales. 

La idea es bien sencilla. XAML conoce una parte de la clase que define la ventana, y el programador conoce otra. Luego el compilador las une y hemos conseguido nuestro objetivo.

Pues bien, C++/CX implementa clases parciales de forma casi idéntica a C#. Es la única forma de que C++ pueda entenderse con XAML sin hacer virguerías todavía peores. 

En resumen:

No está definido en el estándar de C++11.

Sólo funciona para ref class. O en otras palabras: no vale para código C++ clásico ni para la parte clásica de una aplicación Metro escrita en C++/CX.

Se añade una nueva palabra reservada, partial, que debe ir en todas las declaraciones menos en una. 

Tomándolo del artículo en inglés en el que me baso, os pego un ejemplo:

 

// foo.private.h

#pragma once

 

partial ref class foo // <- here the partial keyword is used

{

private:

   int _id;

   Platform::String^ _name;

};

// foo.public.h

#pragma once

#include “foo.private.h”

 

ref class foo // <- partial keyword is not used here

{

public:

   int GetId();

   Platform::String^ GetName();

};

// foo.cpp

#include “pch.h”

#include “foo.public.h”

 

int foo::GetId() {return _id;}

Platform::String^ foo::GetName {return _name;}

 

Es decir, cuando declaremos una clase en varios ficheros, todos ellos deben llevar la palabra reservada partial excepto uno de ellos, que hará de concentrador. Supongo que esto facilita la tarea del compilador, que irá anotando las partes parciales y las irá añadiendo poco a poco a la otra de forma dinámica y conforme se vaya encontrando el código. Y finalmente, en uno o más CPP definimos los métodos y demás. Aquí ya no hace falta para nada la palabra partial porque eso ya lo podíamos hacer antes sin problema alguno.

Esto nos lleva al dibujo siguiente, tomado también del artículo citado:

 

xaml_cpp

 

Eso es lo que hace Visual C++ a la hora de crear una ventana, generando estos cinco ficheros. El XAML contiene la definición de la ventana y todo lo que pongamos dentro, y es idéntico a uno generado en C#. También genera otros dos con los nombres terminados en .g.h y en .g.cpp, que contienen código necesario para que el sistema pueda enlazar el archivo XAML con el código fuente que hayamos podido editar, que a su vez reside en otros dos sendos ficheros con las extensiones de .xaml.h y .xaml.cpp. 

Nuestro código debe ir en los ficheros terminados en xaml (para la definición de la parte visual), xaml.h (para la declaración de la clase que representa la ventana) y xaml.cpp para todo lo demás.

Debemos ser muy cuidadosos en no tocar los otros dos ficheros, que suelen ser generados de forma automática al vuelo por Visual Studio (y supongo que por Blend, pero eso no lo he probado todavía) y que, si hacemos algo mal, podemos tirar abajo el diseñador y luego la aplicación no se cargará bien. Digamos que dichos ficheros son los equivalentes al InitializeComponents() de WindowsForms y que, si los tocamos sin conocimiento de causa, podemos dejar inservible nuestra ventana.

Os dejo que juguéis con lo descubierto. Creaos una aplicación vacía, ponedle un botón o lo que querás y añadidle un evento.

 

 

 

 

2 comentarios en “C++/CX (IV). Clases parciales”

  1. Muy entretenido, como siempre.

    Una única puntualización: con todo lo desagradable que pueda resultar XAML, las clases parciales no son culpa suya y se usaban ya en .NET2.0 (entre otras cosas para el diseñador gráfico de WinForms).

    Un saludo,

    Juanma.

  2. Juanma, iba a darte un palo entre las orejas… hasta que he mirado la MSDN y tienes razón. Para Windows Forms en Visual Studio 2005 no se usaban, pero en 2008 creo que ya sí, dejando atrás a C++/CLI…

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *