|
|
|
|
|
Tdef.h para la enseñanza de plantillas C++
|
Adolfo Di Mare
|
| 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()
|
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() { _top = 0; return; }
void Push(int d) { _vec[_top] = d; _top++; return; }
int Pop() { _top--; return _vec[_top]; }
int Top() { return _vec[_top-1]; }
int Count() { return _top; }
private:
enum { Capacity = 132 };
int _top; // tope de la pila
int _vec[Capacity]; // vector para la pila
}; // Stack_int
|
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() { _top = 0; return; }
void Push(T d) { _vec[_top] = d; _top++; return; }
T Pop() { _top--; return _vec[_top]; }
T Top() { return _vec[_top-1]; }
int Count() { return _top; }
private:
enum { Capacity = 132 };
int _top; // tope de la pila
T _vec[Capacity]; // vector para la pila
}; // Stack_T
|
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() { _top = 0; return; }
void Push(T d) { _vec[_top] = d; _top++; return; }
T Pop() { _top--; return _vec[_top]; }
T Top() { return _vec[_top-1]; }
int Count() { return _top; }
private:
enum { Capacity = 132 };
int _top; // tope de la pila
T _vec[Capacity]; // vector para la pila
}; // Stack_T
|
|
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() { _top = 0; return; }
void Push(T d) { _vec[_top] = d; _top++; return; }
T Pop() { _top--; return _vec[_top]; }
T Top() { return _vec[_top-1]; }
int Count() { return _top; }
private:
enum { Capacity = 132 };
int _top; // tope de la pila
T _vec[Capacity]; // vector para la pila
}; // Stack
|
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.
El truco del "Tdef.h" tiene varias ventajas
importantes:
Miguel Angel Prieto, Manuel Enrique Bermúdez y Alejandro Di Mare aportaron varias observaciones y sugerencias importantes para mejorar este trabajo.
|
|
| [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
|
| [-] | Resumen
|
| [-] | Conclusión
|
| [-] | Agradecimientos
|
| |
|
|
Bibliografía
|
|
Indice
|
|
Acerca del autor
|
|
Acerca de este documento
|
|
Principio
Indice
Final
|
| 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. |
Adolfo Di Mare <adolfo@di-mare.com>
| 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: |
![]() |
![]() |
![]() |