[UCR]  
[/\]
Universidad de Costa Rica
Escuela de Ciencias de la
Computación e Informática
[<=] [home] [<>] [\/] [=>]

El truco del Tdef.h para la enseñanza de plantillas C++

Adolfo Di Mare




Resumen [<>] [\/] [/\]

Presentamos una técnica sencilla que facilita la enseñanza de plantillas para el lenguaje C++. We discuss a simple technique to facilitate teaching C++ templates.
int main() {
    Stack_int S;
    int d = -1;

    S.Push(1);    // 1
    S.Push(2);    // 1 2
    S.Push(3);    // 1 2 3
    S.Push(4);    // 1 2 3 4
    S.Push(5);    // 1 2 3 4 5

    d = S.Pop(); // 1 2 3 4    [5]
    d = S.Count();   // 4





    S.Push(6);    // 1 2 3 4 6
    d = S.Count();   // 5
    S.Push(7);    // 1 2 3 4 6 7
    d = S.Count();   // 6

    d = S.Pop(); // 1 2 3 4 6  [7]
    d = S.Count();   // 5

    return 0;
} // main()
Figura 1

      La programación genérica es una idea que tiene más de 20 años de antigüedad pero que siempre ha sido difícil de explicar debido a la necesidad de dominar los conceptos básicos sobre abstracción de algoritmos y abstracción de datos lo que fuerza a los profesores a esperar a un curso avanzado para introducir este tema. Debido que en realidad las plantillas son "polimorfismo de editor de texto" [MDC-91], es posible explicar plantillas pronto, de forma precisa y sencilla, con base en los "macro" del lenguaje C++. En la Figura 1 está un sencillo programa para introducir el concepto de contenedor como un objeto que almacena otros objetos.

int main() {
    Stack_int S;
    // ...
} // main()
class Stack_int {
public:
    Stack_int()      { m_top = 0; return; }
    void Push(int d) { m_vec[m_top] = d; m_top++; return; }
    int  Pop()       { m_top--; return m_vec[m_top]; }
    int  Top()       { return m_vec[m_top-1]; }
    int  Count()     { return m_top; }
private:
    enum { Capacity = 132 };
    int  m_top;           // tope de la pila
    int  m_vec[Capacity]; // vector para la pila
}; // Stack_int
Figura 2: tStack2.cpp

      Los estudiantes comprenden fácilmente que un vector se puede usar para implementar las operaciones de la pila. Por eso la implementación que está en la parte de abajo de la Figura 2 les resulta familiar.

int main() {
    Stack_T S;
    // ...
} // main()
typedef int T;

class Stack_T {
public:
    Stack_T()      { m_top = 0; return; }
    void Push(T d) { m_vec[m_top] = d; m_top++; return; }
    T    Pop()     { m_top--; return m_vec[m_top]; }
    T    Top()     { return m_vec[m_top-1]; }
    int  Count()   { return m_top; }
private:
    enum { Capacity = 132 };
    int  m_top;           // tope de la pila
    T    m_vec[Capacity]; // vector para la pila
}; // Stack_T
Figura 3: tStack3.cpp

      En la Figura 3 se muestra el resultado de hacer unos pequeños cambios con el editor de textos para obtener la clase "Stack_T" cuya funcionalidad es similar a la de la clase "Stack_int" de la Figura 2. Es sencillo para los alumnos entender las ventajas de contar con una clase más general pues basta modificar una única línea de código para obtener una clase genérica:
      "typedef int T;"

// Tdef.h

#ifndef Tdef_h
    #define Tdef_h
    typedef  int T;
#endif // Tdef_h
// Tdef.h

#ifndef Tdef_h
    #define Tdef_h
    #define T int
#endif // Tdef_h
#ifndef Tdef_h
    #include "Tdef.h"
#endif // Tdef_h

class Stack_T {
public:
    Stack_T()      { m_top = 0; return; }
    void Push(T d) { m_vec[m_top] = d; m_top++; return; }
    T    Pop()     { m_top--; return m_vec[m_top]; }
    T    Top()     { return m_vec[m_top-1]; }
    int  Count()   { return m_top; }
private:
    enum { Capacity = 132 };
    int  m_top;           // tope de la pila
    T    m_vec[Capacity]; // vector para la pila
}; // Stack_T
Figure 4: tStack4.cpp

      El truco del "Tdef.h" consiste en trasladar la línea en que se define el tipo de dato almacenado en la pila a un archivo de encabezado llamado "Tdef.h". El programa principal es el mismo que se usó en la Figura 2. En la parte de arriba de la Figura 4 hay 2 versiones del archivo "Tdef.h" que sirve para parametrizar la pila. Al explicar por qué es necesario usar las directivas de compilación condicional "#ifndef" se puede también explicar cómo funcionan las macros y el preprocesador C++.

int main() {
    Stack<int> S;
    // ...
} // main()
template <class T>
class Stack {
public:
    Stack()        { m_top = 0; return; }
    void Push(T d) { m_vec[m_top] = d; m_top++; return; }
    T    Pop()     { m_top--; return m_vec[m_top]; }
    T    Top()     { return m_vec[m_top-1]; }
    int  Count()   { return m_top; }
private:
    enum { Capacity = 132 };
    int  m_top;           // tope de la pila
    T    m_vec[Capacity]; // vector para la pila
}; // Stack
Figura 5: tStackT.cpp

      Después de haber definido la clase genérica es relativamente sencillo transformarla en una clase con plantillas, como la de la Figura 5. Muchos alumnos escogen usar la clase que usa "Tdef.h", sin plantillas, porque al codificar un programa el compilador emite errores con un significado más fácil de entender que si usaran plantillas. Los estudiantes lo prefieren a pesar de la limitación que tiene el contenedor pues sólo permite un tipo de datos.

      Los resultados de usar esta técnica didáctica son muy buenos, pues toma un alrededor de 2 horas introducir los conceptos de plantillas después de haber cubierto el preprocesador C++ y sus "macros". Debido a que los estudiantes comprenden cómo funciona el mecanismo de sustitución textual para plantillas, pueden escribir y depurar sus programas genéricos con un esfuerzo relativamente pequeño, pues primero construyen la versión "Tdef.h" y luego la "emplantillan" cuando ya está depurada.


Conclusión [<>] [\/] [/\]

      El truco del "Tdef.h" tiene varias ventajas importantes:


Agradecimientos [<>] [\/] [/\]

      Miguel Angel Prieto, Manuel Enrique Bermúdez y Alejandro Di Mare aportaron varias observaciones y sugerencias importantes para mejorar este trabajo.


Bibliografía [<>] [\/] [/\]


           
[AHU-84] Aho, Alfred V.; Hopcroft, John E.; Ullman, Jefrrey D.: Data Structures and Algorithms, Addisson Wesley Publishing Co., 1984.
[Low-2003] Lowy, Juval: An Introduction to C# Generics, Microsoft MSDN Library; August 2003.
      http://msdn.microsoft.com/library/en-us/dnvs05/html/csharp_generics.asp
[MDC-91] Morrison, P. & Dearle, A. & Connor, R. C. H. & Brown, A. L.: An Ad Hoc Approach to the Implementation of Polymorphism, ACM Transactions on Programming Languages and Systems, Vol.13 No.3, pp [342-371], Julio 1991.
      http://www.dcs.st-and.ac.uk/research/publications/download/MDC+91.pdf
[Str-98] Stroustrup, Bjarne: The C++ Programming Language, 3rd edition, ISBN 0-201-88954-4; Addison-Wesley, 1998.
      http://www.research.att.com/~bs/papers.html

Indice [<>] [\/] [/\]

[-] Resumen
[-] Conclusión
[-] Agradecimientos

Bibliografía
Indice
Acerca del autor
Acerca de este documento
[/\] Principio [<>] Indice [\/] Final

Acerca del autor [<>] [\/] [/\]

Adolfo Di Mare: Investigador costarricense en la Escuela de Ciencias de la Computación e Informática [ECCI] de la Universidad de Costa Rica [UCR], en donde ostenta el rango de Profesor Catedrático. Trabaja en las tecnologías de Programación e Internet. Es Maestro Tutor del Stvdivm Generale de la Universidad Autónoma de Centro América [UACA], en donde ostenta el rango de Catedrático. Obtuvo la Licenciatura en la Universidad de Costa Rica, la Maestría en Ciencias en la Universidad de California, Los Angeles [UCLA], y el Doctorado (Ph.D.) en la Universidad Autónoma de Centro América.
Adolfo Di Mare: Costarrican Researcher at the Escuela de Ciencias de la Computación e Informática [ECCI], Universidad de Costa Rica [UCR], where he is full professor. Works on Internet and programming technologies. He is Tutor at the Stvdivm Generale in the Universidad Autónoma de Centro América [UACA], where he is Cathedraticum. Obtained the Licenciatura at UCR, and the Master of Science in Computer Science from the University of California, Los Angeles [UCLA], and the Ph.D. at the Universidad Autónoma de Centro América.
[mailto]Adolfo Di Mare <adolfo@di-mare.com>

Acerca de este documento [<>] [\/] [/\]

Referencia: Di Mare, Adolfo: El truco del Tdef.h para la enseñanza de plantillas C++ , I Congreso Internacional de Computación 2005, Universidad Nacional de Costa Rica, setiembre 2005.
Internet: http://www.di-mare.com/adolfo/p/tdef.htm
Autor: Adolfo Di Mare <adolfo@di-mare.com>
Contacto: Apdo 4249-1000, San José Costa Rica
Tel: (506) 207-4020       Fax: (506) 438-0139
Revisión: ECCI-UCR, Octubre 2004
Visitantes:

Copyright © 2004 Adolfo Di Mare
Derechos de autor reservados © 2004 Adolfo Di Mare <adolfo@di-mare.com>
[home] [<>] [/\]