La Forma Canónica Ortodoxa
La Forma Canónica Ortodoxa u Orthodox Canonical Form (OCF) es un modismo muy utilizado en C++ y definido por James Coplien en su libro Advanced C++: Programming Styles and Idioms. Este modismo permite que un tipo(clase) definido por el programador se comporte como un «tipo concreto de dato», es decir, tenga las mismas características que un tipo proporcionado por el lenguaje.
- Es canónica en el sentido de que se atiene a unas reglas preestablecidas (por el lenguaje).
- Es ortodoxa porque es conforme a las prácticas generalmente aceptadas y que mejor aprovecha las características del lenguaje.
Imagina que quieres hacer una clase String para manejar cómodamente cadenas de caracteres y suplir las deficiencias de los array de caracteres de C (aunque C++ ya tiene una clase string mucho mejor que la que vas a hacer tú :-P) Lo de hacer el String es porque es el ejemplo típico para explicar OCF y no quería deshonrar la tradición.
Si quieres que cumpla la OCF…
Debe tener un constructor sin argumentos
Si no es así, será imposible definir arrays o colecciones(contenedores) de instancias de esa clase. Debes tener presente que si tu clase no tiene ningún constructor, el compilador creará un constructor sin argumentos que hará una inicialización básica de los atributos, los atributos sin constructor por defecto no se inicializarían.
Debe incluir el constructor de copia
Se encarga de que todos los atributos se copien de la forma correcta para obtener una instancia independiente del original. Particularmente importante si la clase tiene atributos de tipo puntero, puesto que el constructor de copia generado por el compilador copiará los punteros y no las variables referenciadas por ellos. El constructor de copia acepta una referencia constante de su mismo tipo como único argumento. No confundir con el operador de asignación.
Aprovecho para definir un método para obtener el tamaño de la cadena que vendrá bien para implementar los demás métodos:
Y ahora sí, el constructor de copia:
Debe implementar el operador de asignación
Se ejecuta cuando se asigna una instancia de la clase a otra. Es importante para evitar problemas en los «temporarios» y en los pasos por valor (por copia) en las llamadas a funciones.
Un destructor
Que se encarga de liberar la memoria de los atributos dinámicos, cerrar ficheros, sockets, etc…
Ampliando la funcionalidad
Aparte de la OCF propiamente dicha, algunos métodos más simplificarán el uso del nuevo tipo.
Constructor de conversión
Para crear fácilmente un String a partir de una array de char.
Operadores de adicción
Ostream inserter
Para que las instancias se pueden imprimir fácilmente:
Declaración de la clase
Download
Este ejemplo está disponible en el repo público