Sie sind auf Seite 1von 46

SEMINARIO C++

Introduccin a la Programacin Orientada a Objetos


Parte 3 v. 20101014
Pedro J. Ponce de Len

Depto. Lenguajes y Sistemas Informticos - Universidad de Alicante

C++
NDICE

1. 2. 3. 4. 5. 6. 7.

Funciones amigas Entrada / Salida Sobrecarga de funciones y operadores Gestin de memoria dinmica Atributos y mtodos de clase Implementacin de relaciones entre objetos Pruebas unitarias

C++

FUNCIONES AMIGAS Funcin Amiga: Funcin NO miembro de una clase, que puede tener acceso a la parte privada de esa clase. Rompe el principio de encapsulacin. Una funcin se declara como amiga de una clase mediante la palabra reservada friend.

class MiClase { friend void unaFuncionAmiga(int, MiClase&); public: //... private: int datoPrivado; };
3

C++

FUNCIONES AMIGAS
void unaFuncionAmiga(int x, MiClase& c) { c.datoPrivado = x; // OK! } int main() { MiClase objeto; unaFuncionAmiga(10,objeto); }

Conceptualmente, las funciones amigas forman parte de la interfaz de una clase (tanto como las funciones miembro).

PROHIBIDO SU USO EN POO: rompen el principio de encapsulacin.

C++
NDICE

1. 2. 3. 4. 5. 6. 7.

Funciones amigas Entrada / Salida Sobrecarga de funciones y operadores Gestin de memoria dinmica Atributos y mtodos de clase Implementacin de relaciones entre objetos Pruebas unitarias

C++

BIBLIOTECA ENTRADA/SALIDA ifstream y ofstream son en realidad clases. La biblioteca iostream (#include <iostream>) define otras clases (ms generales) para los flujos de entrada y salida:

istream : flujo de entrada de caracteres


istream cin;

ostream : flujo de salida de caracteres


ostream cout; ostream cerr;

Nota: Las operaciones de lectura y escritura sobre streams que se presentan a continuacin funcionan para cualquier objeto de tipo istream/ostream (no slo cin y cout).
9

C++

BIBLIOTECA ENTRADA/SALIDA Operaciones de salida:

Operador << cout << 17; Se pueden concatenar llamadas cout << x << y; Algunas operaciones:

Indicar el carcter de relleno: cout.fill(*); // por defecto, espacio en blanco Especificar el nmero mnimo de caracteres para la prxima operacin de salida: cout.width(4); // por defecto, cero

cout.fill(*); cout.width(4); cout << 12 << + << 1; // imprime **12+1 y no **12***+***1 11

C++

BIBLIOTECA ENTRADA/SALIDA Operaciones de entrada


Operador >>. Definido para los tipos bsicos. Salta espacios en blanco (espacio, tabulador o salto de lnea) Entrada numrica:

int x; float y; cin >> x >> y;


Salta espacios y lee dgitos hasta encontrar un espacio en blanco o un carcter no numrico. Importante: si la operacin encuentra un carcter no nmerico, deja el flujo de entrada en estado de error y no almacena nada en la variable; Cuando el formato de entrada no es conocido (por ejemplo, en entrada interactiva), al leer enteros o reales se debe comprobar tras cada lectura que la operacin no ha producido error. Por tanto no es buena idea concatenar lecturas como en el ejemplo de arriba.

13

C++

BIBLIOTECA ENTRADA/SALIDA Operaciones de entrada para carcter


char c; cin >> c;

Salta espacios y guarda en c el primer carcter no blanco.

c=cin.get(); // cin.get(c)

get() devuelve el siguiente carcter en el flujo de entrada. No salta espacios.

14

C++

BIBLIOTECA ENTRADA/SALIDA
Operaciones de entrada para cadenas
string s; cin >> s;

Salta espacios. Almacena caracteres en s hasta encontrar un espacio en blanco o el final del fichero.

Lectura de una lnea completa:

Con cadenas tipo C:


cin.getline(char* destino,int numcar,char delimitador=\n); Lee como mximo numcar-1 caracteres hasta encontrar el carcter delimitador o el final del fichero. No salta espacios. char cadena[100]; cin.getline(cadena, 100); // equiv. a cin.getline(cadena,100,\n);

Con string:
getline(istream& is, string s); Lee una lnea completa de la entrada y la almacena en s (no almacena el salto de lnea final) 15

C++

BIBLIOTECA ENTRADA/SALIDA
Otras operaciones de entrada
cin.ignore()

descarta el siguiente carcter en cin

cin.ignore(int ncar)

descarta ncar caracteres en cin

cin.ignore(int ncar, char delim)

descarta ncar caracteres como mximo hasta llegar al delimitador (que tambin se descarta)

Los mtodos ignore() son tiles para limpiar el flujo de entrada tras un error de lectura.

16

C++

BIBLIOTECA ENTRADA/SALIDA Otras operaciones de entrada


cin.fail() : devuelve cierto si ha habido algn error al leer la entrada cin.eof() : devuelve cierto si se ha alcanzado el final del fichero (se ha intentado leer cuando no haba nada en el buffer de entrada) cin.clear() : recupera al stream del estado "fail".

if (!cin) { // o if (cin.fail()): si ha habido algn error...


cin.clear(); cin.ignore(...); // ...siguiente operacin de lectura } Importante: cuando un flujo de entrada est en estado fail no se puede leer nada de l.
17

C++

BIBLIOTECA ENTRADA/SALIDA: ejemplo


Entrada de datos numricos con formato
void Fecha::leer() { do{ cout<<"Introduce fecha (formato dd/mm/aaaa) <<endl; if (!cin) { cin.clear(); cin.ignore(100,'\n'); } cin >> dia; cin.ignore(); cin >> mes; cin.ignore(); cin >> anyo; } while (!cin); }

19

C++
NDICE

1. 2. 3. 4. 5. 6. 7.

Funciones amigas Entrada / Salida Sobrecarga de funciones y operadores Gestin de memoria dinmica Atributos y mtodos de clase Implementacin de relaciones entre objetos Pruebas unitarias

24

C++

SOBRECARGA DE FUNCIONES
En C++ varias funciones pueden utilizar el mismo nombre (selector) en el mismo mbito, distinguindose por el nmero y tipo de sus argumentos. Estas funciones se dice que estn sobrecargadas. Sobrecarga de funciones miembro (en el mbito de la clase)
class Coordenada { public: ... Coordenada distancia(Coordenada &op2); Coordenada distancia(float &op2); };

En general, cualquier funcin se puede sobrecargar.

25

C++

SOBRECARGA DE OPERADORES En C++ se pueden sobrecargar los operadores del lenguaje para utilizarlos con cualquier tipo de dato, incluso clases definidas por el usuario. Los operadores son en realidad funciones cuyo nombre est formado por la palabra reservada operator seguida del operador a sobrecargar.
int operator+(int,int); float operator+(float,int);

26

C++

SOBRECARGA DE OPERADORES Las expresiones 1), 2) y 3) son equivalentes:


Coordenada a, b(5,3), c(10,10); 1) a=b+c; 2) a.operator=(b.operator+(c)); 3) operator=(a,operator+(b,c));

En 2) los mtodos operator= y operator+ deben ser funciones miembro de la clase. El primer operando es un objeto de la clase (el segundo puede no serlo). En 3) los mtodos no son miembros de la clase. Se debe respetar el significado original de los operadores para no confundir al usuario.
27

C++

SOBRECARGA DE OPERADORES. Asignacin

Sobrecarga del operador de asignacin (=)


Fecha& operator=(const Fecha& f) { if (this!=&f) // proteccin contra autoasignacin { d=f.d; m=f.m; a=f.a; } return *this; }

Es un ejemplo de sobrecarga de un operador binario que modifica al objeto (operando de la izquierda):

Se almacena el resultado de la operacin en el propio objeto Se devuelve referencia al objeto (esto permite concatenar operadores)

Fecha a,b,c; a=b=c; // a.operator=(b.operator=(c));


28

C++
NDICE

1. 2. 3. 4. 5. 6. 7.

Funciones amigas Entrada / Salida Sobrecarga de funciones y operadores Atributos y mtodos de clase Gestin de memoria dinmica Implementacin de relaciones entre objetos Pruebas unitarias

38

Atributos y mtodos de clase

Tambin llamados estticos. Se representan subrayados en UML. Los atributos de clase son comunes a todos los objetos de la clase. Slo existe una copia en memoria compartida por todos los objetos. Los mtodos de clase slo pueden acceder directamente a atributos de clase
39

Atributos y mtodos de clase

class Fecha { public: static const int semanasPorAo = 52; static const int diasPorSemana = 7; static const int diasPorAnyo = 365; static string getFormato(); static boolean setFormato(string); private: static string cadenaFormato; };

40

Atributos y mtodos de clase:


Definicin y acceso
//Fecha.cc // Definicin de un atributo de clase no constante string Fecha::cadenaFormato = DD/MM/AAAA; // Definicin de metodo esttico string Fecha::getFormato() { return cadenaFormato; }

// main.cc (Acceso) int main() { Fecha f; cout << Fecha::semanasPorAnyo << << f.diasPorSemana << endl; cout << Fecha::getFormato() << << f.getFormato() << endl; }

41

C++
NDICE

1. 2. 3. 4. 5. 6. 7.

Funciones amigas Entrada / Salida Sobrecarga de funciones y operadores Atributos y mtodos de clase Gestin de memoria dinmica Implementacin de relaciones entre objetos Pruebas unitarias

42

C++

GESTIN DE MEMORIA DINMICA (recordatorio)


Operadores new y delete
new
Dato *pDato = new Dato; Dato *pArray = new Dato [nElem] ; Comprobacin error: if (pDato==NULL)... Ventaja frente a array convencional: permite decidir el nmero de elementos en tiempo de ejecucin.

delete
delete pDato; pDato=NULL; delete [] pArray; pArray=NULL;

IMPORTANTE: No olvidar los corchetes en delete si los hemos usado en el new correspondiente

43

C++

GESTIN DE MEMORIA DINMICA Array de objetos

Hay que guardar memoria para dos conceptos


El array en s mismo Cada uno de los objetos que componen el array Con variables automticas, C++ permite hacer ambas cosas en una sola lnea:
Naipe arrayDeCartas[52]; //invoca a ctor. por defecto de Naipe para cada componente

Con memoria dinmica:


Naipe *arrayDeCartas[52]; arrayDeCartas = new *Naipe[52]; // Array de punteros for (int i=0; i<52; i++) arrayDeCartas[i] = new Naipe(); // permite invocar a ctores. sobrecargados
44

C++
NDICE

1. 2. 3. 4. 5. 6.

Funciones amigas Entrada / Salida Sobrecarga de funciones y operadores Atributos y mtodos de clase Gestin de memoria dinmica Implementacin de relaciones entre objetos

49

Implementacin de relaciones Asociacin/Agregacin -> mediante punteros Persona


- string nombre - string dni
+ bool anyadeAsig(Asignatura &a) class Asignatura {...}; class Persona { private: string nombre; string dni; vector<Asignatura*> amatr; public: Persona() : amatr() {} ~Persona() { amatr.clear(); // no destruye los objetos Asignatura } void setNombre(string n); string getNombre(); bool anyadeAsig(Asig &a) { amatr.push_back(&a); } }; 50

0..10

Asignatura

- amatr

- string nombre - string crditos


+ bool asignaAlumno(Persona &p)

Implementacin de relaciones Composicin


Composicin: Un objeto A tiene (contiene, esta formado por) objetos B

A
1 -b 10

A
-b 0..10

A
-b 0..*

A
-b

B
class A { private: B b; };

B
class A { private: vector<B*> b; };

class A { class A { private: private: static const int MAXB=10; static const int vector<B*> b; MAXB=10; public: vector<B*> b; A() { }; for (int i=0; i<10; i++) b.push_back(new B());} };

52

Implementacin de relaciones Composicin


A::A(): b() { } A::~A() { for (int i=0; i<b.size(); i++) { } delete b[i]; b[i]=NULL; }
Los componentes B desaparecen con A

A
0..10 -b

Inicialmente A no contiene ningn B

A::addB(B& unB) { if (b.size()<MAXB) b.push_back(new B(unB)); }

b.clear();

class A { private: static const int MAXB=10; vector<B*> b; };

A::A(const A& otroA)


El objeto de tipo A tiene su propia copia de componentes B

: b(otroA.b.size()) { // deep copy for (int i=0; i<b.size(); i++) b[i] = new B(*(otroA.b[i])); } 53

Implementacin de relaciones Composicin


A::A(): b() { } A::~A() { for (int i=0; i<b.size(); i++) A::addB(const B& unB) { { } delete b[i]; b[i]=NULL; } b.clear();

A
* -b
b.push_back(new B(unB)); }

A::A(const A& otroA) {

class A { private: vector<B*> b; };

// deep copy for (int i=0; i<otroA.b.size(); i++) b.push_back(new B(*(otroA.b[i])));

54

C++
NDICE

1. 2. 3. 4. 5. 6. 7.

Funciones amigas Entrada / Salida Sobrecarga de funciones y operadores Atributos y mtodos de clase Gestin de memoria dinmica Implementacin de relaciones entre objetos Pruebas unitarias

55

C++

PRUEBAS UNITARIAS

La interfaz de una clase debe ser probada de manera sistemtica. Una prueba unitaria comprueba que un mtodo determinado, ante una llamada determinada, se comporta como se espera.
Se realiza un caso de prueba unitaria para cada funcin no trivial o mtodo de forma que cada caso sea independiente del resto.

Las pruebas se realizan mediante aserciones

56

C++

PRUEBAS UNITARIAS Herramientas de prueba Son unas colecciones de clases con las que se pueden desarrollar casos de prueba fcilmente. Para c++ existen multitud de herramientas: CPPUnit. Boost.Test. CPPUnitLite. NanoCPPUnit. Unit++. CxxTest <-- Usaremos sta
58

C++

PRUEBAS UNITARIAS: CXXTEST


Herramienta especifica de C/C++. Se considera una de las herramientas ms sencillas y potentes en comparacin con el resto. Es software libre (GNU Lesser Public License) Slo necesita un compilador de c++ ligeramente moderno y actualizado y soporte para alguno de los dos lenguajes en los que se basa: Python o Perl.

59

C++

PRUEBAS UNITARIAS: CXXTEST Instalacin 1. Obtener CXXTEST: http://cxxtest.sourceforge.net 2. Desempaquetar en un subdirectorio test (normalmente en el directorio de trabajo) (para las prcticas de POO, CXXTEST vendr preinstalado en los autocorrectores).

60

C++

PRUEBAS UNITARIAS: CXXTEST


Uso Las pruebas se organizan en clases escritas en ficheros .h; Cada mtodo cuyo nombre comience por test es ejecutado por cxxtest. Por ejemplo:
// MyTestSuite.h #include <cxxtest/TestSuite.h> class MyTestSuite : public CxxTest::TestSuite { public: void testAddition( void ) { TS_ASSERT( 1 + 1 > 1 ); TS_ASSERT_EQUALS( 2 * 2, 5 ); } };
61

C++

PRUEBAS UNITARIAS: CXXTEST Ejecucin de las pruebas:


$ cxxtestgen.pl --error-printer -o runner.cpp MyTestSuite.h $ g++ -o runner runner.cpp $ ./runner

Resultado:
Running 2 tests. MyTestSuite.h:15: Expected (2 * 2 == 5), found (4 != 5) Failed 1 of 2 tests Success rate: 50%

62

C++

PRUEBAS UNITARIAS: CXXTEST Especificacin de casos de prueba mediante aserciones TS_ASSERT Es la prueba bsica. Comprueba que una expresin es cierta. void testCalculadora() { TS_ASSERT( suma( 0, 0 ) == 0 ); }
63

C++

PRUEBAS UNITARIAS: CXXTEST


Especificacin de casos de prueba mediante aserciones

TS_ASSERT_EQUALS Verifica la igualdad entre dos expresiones. Equivalente al operador == en TS_ASSERT. void testResta() { TS_ASSERT_EQUALS(resta(4,2),2); }
64

C++

PRUEBAS UNITARIAS: CXXTEST


Especificacin de casos de prueba mediante aserciones

TS_ASSERT_DELTA Se usa para comparar si dos valores son iguales hasta delta. Bsicamente se usa para nmeros en coma flotante. void testSqrt( void ) { TS_ASSERT_DELTA(sqrt(4.0), 2.0, 0.00001); }
65

C++

PRUEBAS UNITARIAS: CXXTEST


Especificacin de casos de prueba mediante aserciones

TS_ASSERT_DIFFERS Es lo contrario a TS_ASSERT_EQUALS. Se usa para comprobar que dos valores son distintos. Es equivalente a usar != en TS_ASSERT. void testNumeros ( void ) { TS_ASSERT_DIFFERS(5,7); }
66

C++
TS_WARN

PRUEBAS UNITARIAS: CXXTEST


Especificacin de casos de prueba mediante aserciones

Muestra una lista de mensajes de cosas por hacer del tipo to do. void testToDoLista( void ) { TS_WARN( "TODO: Escribir todos );

los test!"

67

C++

PRUEBAS UNITARIAS: CXXTEST


Especificacin de casos de prueba mediante aserciones

TS_FAIL Muestra un fallo incondicional. void testFallo() { TS_FAIL( "No se puede testear." ); }

68

C++

PRUEBAS UNITARIAS: CXXTEST


Dada una clase a evaluar, basta incluir su .h en el fichero de pruebas. Por ej., dada la clase Coordenada de la prctica 0:
#ifndef PUNTO_TESTSUITE_H_ #define PUNTO_TESTSUITE_H_ #include <cxxtest/TestSuite.h> #include "../include/Punto.h"

class PuntoTestSuite : public CxxTest::TestSuite { Punto* c00; Punto* c11; public: void setUp() { // Cdigo que se ejecuta antes de cada prueba c00 = new Punto; c11 = new Punto; c11->setX(1.0); c11->setY(1.0); } void tearDown() { // Cdigo que se ejecuta despus de cada prueba delete c00; c00=NULL; delete c11; c11=NULL; } ...

69

C++

PRUEBAS UNITARIAS: CXXTEST


// (Continuacin) void testFormaCanonica() { // Prueba unitaria: mtodo cuyo nombre empieza por test TS_ASSERT_EQUALS(c11->getX(), 1); TS_ASSERT_EQUALS(c11->getY(), 1); // Test constructor de copia const Punto c(*c11); TS_ASSERT_EQUALS(c.getX(),1.0); TS_ASSERT_EQUALS(c.getY(),1.0); // Test operator= Punto c7; c7.setX(2); c7.setY(3); c7=c7; TS_ASSERT_EQUALS(c7.getX(),2.0); TS_ASSERT_EQUALS(c7.getY(),3.0); c7=*c11; TS_ASSERT_EQUALS(c7.getX(),1.0); TS_ASSERT_EQUALS(c7.getY(),1.0); } };

70

SEMINARIO C++
Introduccin a la Programacin Orientada a Objetos
FIN parte III

Das könnte Ihnen auch gefallen