Programación Avanzada

Documentos relacionados
Programación Avanzada CONCEPTOS BÁSICOS DE IMPLEMENTACIÓN EN C++

Introducción a C++ y Code::Blocks

LABORATORIO #1 INTRODUCCIÓN AL LENGUAJE DE PROGRAMACIÓN C++

Programación 1. Tema I. Conceptos y elementos básicos de Programación. Lección 2. Lenguaje de programación y ejecución de un programa

Tema: Plantillas en C++.

Programación 1 Tema 3. Información, datos, operaciones y expresiones

Tema 5: Herramientas de programación y diseño modular

Tema: Funciones Virtuales y Polimorfismo.

Tema: Funciones Virtuales y Polimorfismo.

CONTENIDO. Programación orientada a objetos - POO. Clases. Constructores y destructores. Definiciones. Entrada y salida

Taller #1 (versión del 18 de septiembre de 2009) Programación básica y aproximación al paradigma orientado a objetos

PROGRAMACIÓN ORIENTADA A OBJETOS

Tema 5: Diseño modular. Índice. Notas. Programación 2. Curso Notas. Ejemplo. La herramienta make. 1 Diseño modular.

Tema 1. Programación modular. Programación Avanzada Ingeniería Técnica en Informática de Gestión Jorge Badenas

Objetivo N 2. Conocer la Estructura General de un Programa en C++ Estructura de Datos Prof. Egilde Márquez

MANEJO DE EXCEPCIONES en C++ Dr. Oldemar Rodríguez R. Escuela de Informática Universidad Nacional

Introducción a clases en C++

Tema: Punteros a Objetos. Puntero this.

Programación 1 Tema 3. Información, datos, operaciones y expresiones

Programación C++ (1 Parte) Dr. Oldemar Rodríguez Rojas Escuela De Informática Universidad Nacional

Programación orientada a objetos I

Macros LENGUAJE DE PROGRAMACIÓN ESTRUCTURADO

Lenguaje de Programación: Compiladores de C y C++

LENGUAJE DE PROGRAMACION I. Ing. JAVIER ECHEGARAY ROJO Ing. WILDER ROMAN MUNIVE. Ing. Javier Echegaray Rojo / Ing. Wilder Román Munive Pag 1

Guía del Entorno de Programación en GNU/Linux

Lenguaje de Programación: C++ Directivas al preprocesador

Templates. template <class T> T max(const T &t1, const T &t2) { return ((t2 > t1)? t2 : t1); }

Tema: Sobrecarga de Operadores Unarios. Sobrecarga de Funciones.

ALMACENAMIENTO PERSISTENTE DE DATOS

PRÁCTICA DE LABORATORIO 4 Programación Orientada a Objetos

UNIVERSIDAD DE LOS ANDES NUCLEO UNIVERSITARIO RAFAEL RANGEL (NURR) DEPARTAMENTO DE FISICA Y MATEMATICA AREA COMPUTACION TRUJILLO EDO.

Capítulo 6. Introducción a la POO

Lenguaje de Programación

2. Problema de Algoritmia (5 puntos - 15 minutos)

Programación Avanzada

La Herencia. La primera línea de cada declaración debe incluir la sintaxis siguiente:

Tema: Sobrecarga de Operadores.

Unidad V. Ya veremos qué poner en "algunas_palabras" y "algo_más", por ahora sigamos un poco más.

Programación 1 Problemas del Composición condicional

Seminario C++ Introducción a la programación orientada a objetos. Parte IV v Cristina Cachero Pedro J. Ponce de León

Fundamentos Programación Orientada a Objetos ( POO ) - Parte I Desarrollo de Software

Estructuras de control selectivas

Tipos Recursivos de Datos

Clases en C++ Universidad de Carabobo Facultad Experimental de Ciencias y Tecnología Algoritmos y Programación II. Enero de 2005

Introducción a C++ Índice

INTRODUCCIóN A LA PROGRAMACIóN APUNTES DE JAVA APUNTES DE JAVA

En el siguiente ejemplo se declara un registro y luego variables de ese tipo de registro:

Tema: Tabla de Símbolos

PUBLICACIÓN DEL ENUNCIADO: Semana del 10 de noviembre de ENTREGA: Clase de laboratorio de la semana del 8 de diciembre de 2003.

Laboratorio 5 Tema 7. Tipos de Datos Estructurados: Arreglos, Registros y Archivos

Tema 5: Traducción dirigida por la sintaxis

Clases y Objetos en C++

Unidad Didáctica 1. Introducción a la Programación Orientada a Objetos (POO) Conceptos de clase, objeto e interfaz. Atributos y métodos

Memoria Dinámica en C++

Introducción a la Programación orientada a objetos con C++

Tema 6: Memoria dinámica

Programación 1. Tema II. Diseño de programas elementales. Lección 7. Diseño modular y descendente de programas

USO DE SUBRUTINAS, TRANSMISIÓN DE PARÁMETROS Y COMPILACIÓN CONDICIONAL EN C++

Introducción al lenguaje C

UTN FRBA Algoritmos y Estructura de Datos Examen Final 13/02/2015. Apellido y nombre: Legajo: Cursó con Prof:

Introducción al laboratorio de Programación I

Lenguaje C. República Bolivariana de Venezuela Fundación Misión Sucre Aldea Fray Pedro de Agreda Introducción a la Programación III

Arboles Binarios de Búsqueda en C++

Tipos de Datos Simples Contenido del Tema

Guía de estilo y buenas prácticas de programación en C/C++

Ámbito y Funciones. Lenguaje de Programación Estructurado. Siempre imaginé el Paraíso como algún tipo de biblioteca.

ESCUELA DE INGENIERÍA DE SISTEMAS DEPARTAMENTO DE COMPUTACIÓN PROGRAMACIÓN 2 PRÁCTICA DE LABORATORIO 7 Herencia y Composición en POO

República Bolivariana de Venezuela Aldea Universitaria Liceo Fray Pedro de Agreda Trayecto II Desarrollo de Software

Programación Orientada a Objetos en C++

Principios de Computadoras II

Tema: Punteros.Puntero this en C#.

Examen escrito de Programación 1

ELO329: Diseño y Programación Orientados a Objetos 20 de Junio de Certamen Final

Fundamentos de la programación

26 de Octubre del 2013

Funciones: Pasos por Referencia Recursividad

Tema: Autómatas de Estado Finitos

Clases y métodos parciales (Guía de programación de C#)

Programación con Multitareas

Tema 05: Elementos de un programa en C

Estructuras de Datos Declaraciones Tipos de Datos

Java Avanzado Facultad de Ingeniería. Escuela de computación.

CONTENIDO DE LA LECCIÓN 21

Estructuras Enlazadas AyED UTN-BA

Cátedra I Informática Autor I Carlos Bartó

1. Sobrecarga de operadores. 2. Métodos operadores unarios Operador de incremento (prefijo)

TP N 14 Compilando C/C++ bajo GNU/Linux

Guia#9: Punteros en C#.

Inicio de la sesión de trabajo

Programación de Computadores 4 Iteraciones y Decisiones. Prof. Javier Cañas. Universidad Técnica Federico Santa María Departamento de Informática

Laboratorio de Informática GRADO EN FÍSICA

Algo sobre Makefiles

Fundamentos de la programación

Práctica 8: Barreras

LISTAS ENLAZADAS DOBLES C++

Introducción al Depurador de Dev-C++

APUNTES PROII 2º PARCIAL.

Sobre Carga de Operadores

Impresión por pantalla. 3. Indicar la salida por pantalla (2 puntos-20 minutos)

TEMA 3:Programación con Clases y Objetos.

Transcripción:

Programación Avanzada Referencias Circulares y Namespaces 1

Índice 1. INTRODUCCIÓN.. 3 2. REFERENCIAS CIRCULARES.. 4 Ejercicio 1 4 Ejercicio 2 4 Ejercicio 3 5 3. NAMESPACES 6 Introducción 6 Creación de namespaces 7 Utilización de namespaces 7 Utilizando el operador :: 8 Utilizando la palabra reservada using. 8 El namespace de la biblioteca estándar de C++.. 8 Ejercicio 1 8 Ejercicio 2 9 REFERENCIAS.. 11 2

1. Introducción El objetivo de este documento es servir de guía para empezar a familiarizarse con la problemática de las referencias circulares y los namespaces en el lenguaje C++ [2][3]. Un prerequisito de este documento es haber leído el documento Instructivo de Compilación [1] el cual apunta a ilustrar cómo se usan las herramientas de desarrollo. Básicamente, este instructivo consta de una serie de ejemplos y algún ejercicio sencillo a ser realizado en máquina. 3

2. Referencias Circulares Ejercicio 1 Considere el siguiente diagrama de clases: ClassA ClassB 1 0..1 Observación: La navegabilidad es doble. Una implementación directa de dicho diagrama de clases es: ClassA.hh #ifndef _CLASSA_HH_ #define _CLASSA_HH_ #include "ClassB.hh" class ClassA{ ClassB * myb; ; ClassB.hh #ifndef _CLASSB_HH_ #define _CLASSB_HH_ #include "ClassA.hh" class ClassB{ ClassA * mya; ; Se pide: Completar la implementación con un código simple, construir un makefile e intentar compilar. Si le da error, continúe con el ejercicio 2. Ejercicio 2 Cuando se intente compilar las clases del ejercicio 1 se va a encontrar el problema de las referencias circulares. El hecho de que la clase ClassA necesite a la clase ClassB para ser compilada y viceversa hace que el compilador reporte el error y no pueda concluir su trabajo. Una forma de arreglar este problema es utilizar declaraciones en avanzada (forward declarations). ClassA.hh #ifndef _CLASSA_HH_ #define _CLASSA_HH_ #include "ClassB.hh" class ClassA{ ClassB * myb; ; ClassB.hh #ifndef _CLASSB_HH_ #define _CLASSB_HH_ // Declaración en avanzada de la clase ClassB class ClassA; class ClassB{ ClassA * mya; ; #include "ClassA.hh" 4

De esta manera el compilador es capaz de compilar la clase ClassB sin conocer la definición de la clase ClassA. Por lo tanto se corta el ciclo y la compilación podrá proceder sin problemas. Observación: La compilación se debe realizar de la manera normal. Se pide: Rehacer la implementación del ejercicio 1 utilizando el mecanismo antes explicado para cortar el ciclo de dependencias. Compilar y ejecutar. Ejercicio 3 Implemente el siguiente diagrama de clases: ClassA ClassB 1 0..1 1 0..1 ClassC ClassE 1 0..1 0..1 1 ClassD 1 0..1 Observación: La navegabilidad es doble entre ClassA y ClassB Observación: para poder compilar esto se deben cortar todos y cada uno de los ciclos de dependencias existentes. 5

3. Namespaces Introducción Considere las siguientes clases que representan coordenadas binarias y ternarias: Coordenada.hh #ifndef _COORDENADAB_HH_ #define _COORDENADAB_HH_ class Coordenada { int x; int y; Coordenada(int x = 0, int y = 0); Int getx(); Int gety(); ; Coordenada.hh #ifndef _COORDENADAT_HH_ #define _COORDENADAT_HH_ class Coordenada { int x; int y; int z; Coordenada(int x = 0, int y = 0, int z = 0); Int getx(); Int gety(); Int getz(); ; Ahora considere el siguiente main que transforma una coordenada binaria a una coordenada ternaria. main.cc #include <iostream> #include "Coordenada.hh" using namespace std; int x, y; cout << "Ingrese la coordenada x = "; cin >> x; cout << "Ingrese la coordenada y = "; cin >> y; Coordenada binc(x, y); cout << "Ud. ha ingresado una coordenada binaria = (" << binc.getx() << ", " << binc.gety() << ")" << endl; // Se pasa la coordenada binaria leida a una coordenada ternaria. Coordenada ternc(x, y, 0); cout << "La coordenada ingresada transformada a ternaria = (" << ternc.getx() << ", " << ternc.gety() << ", " << ternc.getz() << ")" << endl; return 0; Es claro que esto acarreará un problema de conflictos de nombres. Se está haciendo referencia a dos clases diferentes, coordenadas ternarias y binarias, con el mismo nombre: Coordenada. Debido a esto, el compilador no podrá decidir a qué se está queriendo referenciar cuando encuentre dicho nombre y por lo tanto no podrá compilar este ejemplo tal cual fue presentado. Para evitar este tipo de conflictos de nombres surgen los namespaces. Como se vio arriba el problema se da cuando desde un mismo archivo de código (.hh o.cc) se necesita utilizar dos 6

clases diferentes que se llaman de la misma forma. En C++, la forma más elegante de subsanar este problema es la utilización de namespaces. La palabra reservada namespace coloca los nombres de sus miembros en una porción particular (identificada por su nombre) del espacio de nombres. A continuación se tratarán algunos detalles sintácticos y semánticos de los namespaces y luego se verá la solución al ejemplo recién planteado en el Ejercicio 1. Creación de namespaces La sintaxis para la creación de un namespace es la siguiente: namespace namespaceid { // Declaraciones Esto produce un nuevo namespace conteniendo las declaraciones hechas dentro de él. La definición de un namespace solamente puede aparecer a nivel global, es decir, no puede estar dentro de la definición una clase o función, pero pueden definirse namespaces anidados. Además dicha definición puede extenderse a múltiples archivos simplemente repitiendo el nombre del namespace: ClassA.hh namespace namespaceid { class ClassA { /* */ ; ClassB.hh namespace namespaceid { class ClassB { /* */ ; Tanto ClassA como ClassB pertenecerán al mismo espacio de nombres namespaceid. Utilización de namespaces Hay dos formas de referenciar a los namespaces: utilizando el scope resolution operator o utilizando la palabra clave using. Supongamos que tenemos el siguiente namespace declarado para estudiar como funcionan ambos mecanismos: namespace nsid { class ClassA { ClassA(); void f(); ; 7

UTILIZANDO EL OPERADOR :: // Cada vez que se quiera utilizar algún elemento del namespace se debera // especificar el nombre totalmente calificado del mismo. nsid::classa * a = new nsid::classa(); a->f(); return 1; UTILIZANDO LA PALABRA RESERVADA USING Incluyendo todo el espacio de nombres (forma general): using namespace nsid; ClassA * a = new ClassA(); a->f(); return 1; using namespace nsid; ClassA * a = new ClassA(); a->f(); return 1; Incluyendo solamente lo que se va a utilizar (forma más específica): using namespace nsid::classa; ClassA * a = new ClassA(); a->f(); return 1; using namespace nsid::classa; ClassA * a = new ClassA(); a->f(); return 1; Por más información acerca de los espacios de nombres en C++ referirse a [3]. El namespace de la biblioteca estándar de C++ La biblioteca estándar de C++ se encuentra en el espacio de nombres llamado std. Por este motivo, cada vez que se quiera utilizar cualquiera de las funcionalidades de la misma, además de incluir los archivos correspondientes se deberá utilizar alguno de los mecanismos vistos en la sección anterior para acceder a dicho namespace. Ejercicio 1 Considere la siguiente solución al ejemplo que se encuentra en la sección Introducción del tema Namespaces: Coordenada.hh #ifndef _COORDENADAB_HH_ #define _COORDENADAB_HH_ namespace binario { class Coordenada { int x; int y; Coordenada.hh #ifndef _COORDENADAT_HH_ #define _COORDENADAT_HH_ namespace ternario { class Coordenada { int x; int y; int z; 8

Coordenada(int x = 0, int y = 0); int getx(); int gety(); ; Coordenada(int x = 0, int y = 0, int z = 0); int getx(); int gety(); int getz(); ; main.cc #include <iostream> #include "./binario/coordenada.hh" #include "./ternario/coordenada.hh" using namespace std; int x, y; cout << "Ingrese la coordenada x = "; cin >> x; cout << "Ingrese la coordenada y = "; cin >> y; // Se utiliza el operador :: para explicitar a que clase se refiere. binario::coordenada binc(x, y); cout << "Ud. ha ingresado una coordenada binaria = (" << binc.getx() << ", " << binc.gety() << ")" << endl; // Se pasa la coordenada binaria leida a una coordenada ternaria. // Se utiliza el operador :: para explicitar a que clase se refiere. ternario::coordenada ternc(x, y, 0); cout << "La coordenada ingresada transformada a ternaria = (" << ternc.getx() << ", " << ternc.gety() << ", " << ternc.getz() << ")" << endl; return 0; Se pide: a) Pase el ejemplo a la máquina. b) Construya los archivos Coordenada.cc para ambas clases. c) Construya un makefile para compilarlo y linkeditarlo. d) Ejecute el ejemplo construido. Observación: Notar que como los archivos que contienen las clases se llaman de igual manera se crearon dos subdirectorios, llamados de igual forma que los namespaces binario y ternario (por claridad), para almacenar dichos archivos. En definitiva, la estructura de directorios sería la siguiente: main.cc Coordenada.cc, Coordenada.hh (la coordenada binaria) Coordenada.cc, Coordenada.hh (la coordenada ternaria) Ejercicio 2 Compile y ejecute los siguientes ejemplos con motivo de entender cómo resuelve C++ los conflictos de nombres. 9

a) #include <iostream> b) using std::cout; using std::endl; namespace test { int i = 2; class Aux { int i; Aux() { i = 1; ; void accesstest() { cout << "El valor del atributo 'i' es: " << i << endl; int i = 0; // Podria ser la variable local o el atributo cout << "El valor de 'i' es: " << i << endl; cout << "El valor del atributo 'i' es: " << this->i << endl; cout << "El valor de la variable 'i' del namespace test: " << test::i << endl; using namespace test; // Podria ser la variable del namespace, el atributo o la variable local cout << "El valor de 'i' es: " << i << endl; Aux *a = new Aux(); a->accesstest(); Cambie la línea using namespace test; por la línea using test::i; Explique el comportamiento observado. 10

4. Referencias [1] Instructivo de Compilación. Página del curso de Programación Avanzada [2] Tutorial de C++. www.cplusplus.com/doc/tutorial/index.html [3] Thinking In C++. http://www.mindview.net/books/ticpp/thinkingincpp2e.html 11