Universidad de Costa Rica
|
|
1) [50 pts] STL + Herencia + polimorfismo
template <class T> class vector { public: T* start; // Rep vector(int n) { start = new T[n]; } ~vector() { delete[] start; } typedef T* iterator; iterator begin() { return start; } iterator end() { return start+n; } T& operator[] (int i) { return T[i]; } }; |
class TMesa : public TAqui { int _p; // # patas int _a; // altura // ... }; // TMesa class TSilla : public TAqui { int _r; // ¿Respaldar? // ... }; // TMesa class TRefri : public TAqui { int _c; // capacidad // ... }; // TRefri |
enum TLugar = {Cuarto, Cocina, Baño}; class TAqui { TLugar _v; public: TAqui() { _v = Cuarto; } ~TAqui() {} void traslade(TLugar d) { _v = d; } }; // TAqui |
Considere las declaraciones que se muestran en la figura de arriba. Recuerde que el Rep de los iteradores que se usan para recorrer un vector es un puntero que tiene, entre otras, las siguientes operaciones:
operator!= () //
Comparación
operator++ () //
Avance al siguiente
operator* () //
Derreferencia
La forma de crear un vector "v[]
" de (punteros a)
objetos para luego trasladarlos al baño usando el iterador
"i
" es la siguiente:
vector <TAqui*> v(3); // 3 elementos v[0] = new TMesa; // & mesa v[1] = new TSilla; // & silla v[2] = new TRefri; // & refri vector::iterator i; for (i = v.begin(); i != v.end(); i++) { *(*i).traslade(Baño); } |
1.a) [25 pts] Reescriba las clases de la
Figura 1 y el programa de la
Figura 2, pero no use plantillas. En
otras palabras, lo que usted debe hacer es instanciar las
plantillas para que el código C++ que resulta no contenga
ninguna instrucción parametrizable. No olvide traducir la
plantilla de la clase vector<>
.
1.b) [25 pts] Compile el programa de la Figura 2 junto con las clases de la Figura 1, pero en lugar de producir código objeto Intel x86, emita código Pascal o C (no C++). No use las facilidades de programmación por objetos de Pascal, ni el macro procesador de C. Recuerde que debe desarrollar en línea las operaciones del vector y del iterador, y que debe instanciar la plantilla del vector adecuadamente.
2) [25 pts] Constructores y destructores
En C++ es inválido invocar a un constructor usando un
puntero a un método. En Turbo Pascal hay que usar
programación de bajo nivel para lograrlo, lo que hace al
programa no portable (recuerde el programa
InitDone.pas
que
está en el enunciado de
una de las tareas programadas que usted
resolvió). Por eso conviene encontrar una forma de hacer
esa tarea sin recurrir a trucos de bajo nivel. Primero considere
la especificación de la operación que se muestra a
continuación:
TObj.Clone(p)
2.a) [10 pts] Implemente la operación
TObj.Clone(p)
en Pascal (no use C++), pero no use
trucos de bajo nivel. Use las operaciones
TObj.Init()
y
TObj.Copy()
para realizar su trabajo.
2.b) [5 pts] Defina la clase abstracta
TObj
, que incluye la operación
polimórfica (VIRTUAL
) Otro()
que
permita crear polimórficamente un nuevo objeto (Stroustrup
les llama a estas operaciones constructores virtuales
[Str98]). Especifique e implemente su
duplicador virtual.
2.c) [8 pts] Explique por qué es necesario
redefinir el constructor virtual Otro()
en cada clase
derivada de TObj
. No estará de más que
incluya un pequeño ejemplo.
2.d) [2 pts] ¿Ocurre lo mismo con
Clone()
?
3) [25 pts] Programación Perl
Haga un programa que lea un grupo de archivos ASCII para obtener de ellos las direcciones electrónicas de las solicitudes que haga. Los archivos contienen colecciones de mensajes de correo electrónico como las que se muestran en la siguiente figura:
From cyberteq3@mafalda.teletel.com.ar Wed May 20 07:51:15 1998 Return-Path: <cyberteq3@mafalda.teletel.com.ar> Received: from teletel.com.ar (200.10.110.101) by mail02.rapidsite.net (8.8.5/8.8.5) with SMTP id JAA03974 for <ci1402@ecci.ac.cr>; Wed, 20 May 1998 09:50:40 -0400 (EDT) Received: from pc3 by teletel.com.ar with smtp (Smail3.1.29.1 #2) id m0yc3eF-000sC; Wed, 20 May 98 10:50 GMT Message-Id: <m0yc3eF-000gcsC@teletel.com.ar> Comments: Authenticated sender is <cyberteq3@mail.teletel.com.ar> From: Juan Ramos <cyberteq3@smail.teletel.com.ar> To: ci1402@ecci.ac.cr Date: Wed, 20 May 1998 10:57:43 +0000 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Carta al estudiante I-Sem-1995 Priority: normal X-mailer: Pegasus Mail for Win32 (v2.53/R1) X-Loop-Detect: 1 Status: RO X-Status: Quiero información sobre el curso para un estudio personal. |
El renglón From:
aparece
siempre antes del renglón Subject:
, y contiene
la dirección de correo electrónico a extraer. En el
renglón Subject:
viene la
indicación de la información a extraer. Para este
ejemplo, al procesar el archivo su programa debe extraer los
siguientes datos:
Juan Ramos <cyberteq3@smail.teletel.com.ar>
http://www.ecci.ac.cr/~ci1402/1995-1
Cada archivo a procesar contiene muchos mensajes. Su programa debe
dejar en la salida estándar todas las parejas de renglones
que extraiga. Sin embargo, cuide de evitar procesar renglones que
no contengan la línea de Subject:
.
Diane Wood Sponheim <dsponhei@luthersem.edu> http://www.ecci.ac.cr/~ci1402/1995-1 Vary Blanco <Vary@hotmail.com> http://www.ecci.ac.cr/~ci1402/1997-2 Concepcion Larios <concep@caribe.net> http://www.ecci.ac.cr/~ci1402/1995-2 Asparagus Jovenus <beavis@hp9000.cpd.uva.es> http://www.ecci.ac.cr/~ci1402/1996-1 Andres Rivera <arivera@quercus.inbio.ac.cr> http://www.ecci.ac.cr/~ci1402/1998-1 Carolina Uribe <mcuribe@reymoreno.net.co> http://www.ecci.ac.cr/~ci1402/1993-3 |
4) [25 pts] Constructores y destructores
El lenguaje C++ estándar no permite que el programador invoque un constructor sin al mismo tiempo crear una nueva instancia de una variable. Para Pascal tampoco hay una forma portable de hacerlo.
4.a) [10 pts] Defina el tipo TClonabe
, en
su lenguaje preferido, que incluye un método
polimórfico Invoca_Constructor()
, que se
encarga de invocar al constructor de un objeto sin requerir la
creación de una nueva instancia. Luego implemente el
método Invoca_Constructor()
usando el
siguiente algoritmo (que fue mencionado en clase):
desde
"
del tipo a construir.pClonable
", la
dirección de memoria sobre la que se invocará
al constructor.desde
" ya construida.
*pClonable
".
Recuerde que para lograr su objetivo debe implementar el
constructor de TClonable
usando una pareja de
métodos diferentes [TClonable.Init()
y
TClonable.Real_Init()
], de manera que pueda
invocarlos por separado.
4.b) [5 pts] Diga qué debe hacer el programador
cliente del tipo TClonabe
para invocar el constructor
de un objeto usando la maquinaria de
Invoca_Constructor()
.
4.c) [5 pts] Explique por qué
Invoca_Constructor()
funciona.
4.d) [5 pts] De un ejemplo de una aplicación en la que conviene que el programador pueda invocar al constructor de la forma en que lo ha hecho al contestar esta pregunta.
5) [25 pts] Recursividad
BajeSuba()
5.a) [0 pts] Escoga dos valores para los argumentos
"primero
" y "n
" del procedimiento
BajeSuba()
, que muestren cómo se realiza la
recursividad.
5.b) [10 pts] Muestre la ejecución del
procedimiento BajeSuba()
para la primera pareja de
argumentos que usted ha escogido. No olvide mostrar el estado de
la pila de ejecución del programa. Asegúrese de que
haya al menos tres llamados recursivos activos en algún
momento.
5.c) [10 pts] Muestre la ejecución del
procedimiento BajeSuba()
para la segunda pareja de
argumentos.
5.d) [5 pts] Use los ejemplos anteriores para explicar qué es recursividad. Redacte su respuesta de manera que la pueda entender un estudiante que recién toma su primer curso de programación.
[Str98] |
Stroustrup, Bjarne:
The C++ Programming Language, 3rd edition,
ISBN 0201889544;
Addison-Wesley, 1998.
http://www.research.att.com/~bs/papers.html
|
Adolfo Di Mare <adolfo@di-mare.com>.
|