Descargar la presentación
La descarga está en progreso. Por favor, espere
1
Clases, Objetos y Métodos (II)
Pablo San Segundo (C-206)
2
Índice Introducción al concepto de clase Elementos de una clase
Implementación: declaración y definición Permisos y encapsulamiento Constructores y destructores Constructor copia Inicialización de objetos miembro Creación dinámica de objetos Calificativo const para objetos Calificativo static para objetos Calificativo friend para objetos
3
Consideraciones generales (1/2)
CONSTRUCCIÓN: Se llama primero al constructor del objeto miembro y luego al del objeto contenedor DESTRUCCIÓN: Se llama primero al destructor del objeto contenedor y después al del objeto miembro (orden inverso) class B{ public: int dato; B() {dato=0; cout<<"llamando al constructor de B sin argumentos"<<endl;} ~B(){cout<<"llamando al destructor de B"<<endl;} }; class A{ B b; //dato miembro objeto de tipo de usuario B public: A() {cout<<"llamando al constructor de A sin argumentos"<<endl;} ~A(){cout<<"llamando al destructor de A"<<endl;} }; void main(){ A a; } CUESTIÓN ¿Salida en pantalla?
4
Consideraciones generales (2/2)
Uso de listas de inicialización class B{ int dato; public: B(int d):dato(d) {} }; CASO-A #include "B.h" class A{ B b; public: A(int dato){b.dato=0;} }; CASO-B #include "B.h" class A{ B b; public: A(int dato):b(dato){} }; CUESTIÓN ¿Diferencias entre el caso A y el caso B?
5
Ejemplo CUESTIÓN ¿Salida en pantalla? DECLARACIONES (A.h) class A{
public: A(){cout<<"Llamada al constructor de A"<<endl;} }; class Foo{ A vector[10]; //colección de 10 objetos A TEST UNITARIO (.cpp) #include "A.h" void main(){ Foo f1; } CUESTIÓN ¿Salida en pantalla?
6
Múltiples objetos miembro
Declaración (.h) class A{ int a1; int a2; B b; //objeto con constructor B(int, int) C c; //objeto con constructor C(int, int) public: A(int a1, int a2); }; Definición (I) (.cpp) A::A(int x, int y):b(x,y), c(x,y) { a1=x; a2=y;} Definición (II) (.cpp) A::A(int x, int y):b(x,y), c(x,y), a1(x), a2(y) {} CUESTIÓN ¿Orden de llamada a los constructores?
7
Constructor copia en objetos miembro
class B{ public: //… B() {cout<<"llamando al constructor de B sin argumentos"<<endl;} B(const B&) {cout<<"llamando al constructor copia de B"<<endl;} }; class A{ B b; A() {cout<<"llamando la constructor de A sin argumentos"<<endl;} A(const A& a): b(a.b){cout<<"llamando al constructor copia de A"<<endl;} CUESTIÓN ¿salida en pantalla? USUARIO (.cpp) void main(){ A a; A a1(a); } REGLA Definido el constructor copia del contenedor, éste tiene TODA la responsabilidad de las copias de sus objetos miembro
8
USUARIO/CLIENTE (.cpp)
Ejercicio Implemente un Mundo con las siguientes características El Mundo tiene una única Esfera La Esfera se define por su radio y sus tres coordenadas espaciales Las coordenadas se agrupan en un struct coord_t La funcionalidad del Mundo debe permitir el código de usuario siguiente: USUARIO/CLIENTE (.cpp) #include "Mundo.h" void main(){ Esfera e(3, coord_t(1.0, 2.0, 3.0)); Mundo m1(e); Mundo m2(m1); }
9
Índice Introducción al concepto de clase Elementos de una clase
Implementación: declaración y definición Permisos y encapsulamiento Constructores y destructores Constructor copia Inicialización de objetos miembro Creación dinámica de objetos Calificativo const para objetos Calificativo static para objetos Calificativo friend para objetos
10
Creación/destrucción dinámica de objetos
Sintaxis new y delete similar a la vista para tipos base con las siguientes diferencias: Llamada al constructor en el momento de la creación (new) Llamada al destructor antes de la liberación de memoria (delete) Llama al constructor predefinido de dos argumentos void main(){ Complex * pcom = new Complex(5.0, 6.0); delete pcom; } OBJETO SIMPLE CUESTIÓN Comparación con malloc y free para objetos Llama al destructor antes de liberar memoria void main(){ int n=10; Complex * pcom = new Complex[n]; delete [] pcom; } ARRAY DE OBJETOS Llama al constructor sin argumentos en los 10 objetos Llama al destructor antes de liberar memoria para cada objeto
11
Índice Introducción al concepto de clase Elementos de una clase
Implementación: declaración y definición Permisos y encapsulamiento Constructores y destructores Constructor copia Inicialización de objetos miembro Creación dinámica de objetos Calificativo const para objetos Calificativo static para objetos Calificativo friend para objetos
12
Se considera calificativo const en los siguientes casos:
Objetos Atributos Paso por referencia de objetos
13
Calificativo const para objetos (1/2)
En C el calificativo de const para una variable de tipo base indica que no puede ser un l-value. En C++ es necesario definir qué se entiende por objetos constantes. El comportamiento de un objeto constante queda caracterizado por sus funciones miembro declaradas como constantes, con la siguiente SINTAXIS: Declaración: se añade const justo antes del “;” Definición (inline o no): se añade const justo antes de “{“ Es posible polimorfismo en funciones miembro con respecto al calificativo const. "CONST" INLINE (.h) class Complex{ //… public: void print() const; }; "CONST" DEFINICION (.cpp) void Complex::print() const { cout<<i<<" "<<j<<endl; } };
14
Calificativo const para objetos (2/2)
Atributos: En el espacio en el que un objeto ha sido declarado const no se pueden modificar (no pueden aparecer como l-values). Aplica también a los atributos de tipo puntero o referencia Existen maneras de saltarse esta protección Ejemplo: se puede modificar el elemento apuntado por un atributo de tipo puntero o referencia DECLARACIÓN (foo.h) class Foo { public: struct s_t{ int dato;}; private: s_t* a; Foo(s_t* a_outer):a(a_outer){} void print() const; }; DEFINICION (Foo.cpp) void Foo::print() const{ a->dato=20; //constness? }
15
Calificativo const para atributos
El calificativo const para datos miembro se emplea para aquellos datos que no modifican su valor a lo largo de la vida del objeto. Sólo toman valores en la llamada al constructor Hay que usar obligatoriamente la lista de inicialización Sintaxis “:” obligatoria DECLARACION (Array.h) class Array{ private: const int SIZE; //… public: Array(int n):SIZE(n){} void set(int n){SIZE=n;} }; INCORRECTO MODIFICA UN DATO DE TIPO CONST
16
Calificativo const en el paso por referencia
Impide que la referencia pasada pueda usarse como un l-value REGLA- Una referencia a un objeto sólo puede acceder a la parte del interfaz público declarada como constante PASO DE UN OBJETO COMO REFERENCIA CONSTANTE A UNA FUNCIÓN void foo(const Complex & c){ c.print(); //print() DEBE SER tipo const }
17
Ejercicio Analice la declaración de la clase ListaNum definida anteriormente en relación con el calificativo const : Mejore el diseño, si procede. Implemente una función independiente que permita visualizar la lista de números de cualquier objeto ListaNum. Defina una función de tipo getter para que el usuario pueda acceder a la lista de números de ListaNum.
18
Índice Introducción al concepto de clase Elementos de una clase
Implementación: declaración y definición Permisos y encapsulamiento Constructores y destructores Constructor copia Inicialización de objetos miembro Creación dinámica de objetos Calificativo const para objetos Calificativo static para objetos Calificativo friend para objetos
19
Calificativo static para objetos
Objetos de tipo static: generalización de las variables estáticas de tipo base en C El ciclo de vida de un objeto declarado static dura hasta el final del programa DECLARACION (Foo.h) class Foo{ int f; public: Foo() {cout<<“llamada al constructor sin parametros”<<endl;} ~Foo() {cout<<“llamada al destructor”<<endl;} //… }; DEFINICION (Foo.cpp) int func(){ static Foo; //… return 0; } void main(){ for(int i=0; i<10; i++) {func();} EJERCICIO ¿Salida en pantalla?
20
Calificativo static para atributos de una clase
Un atributo static es común a todos los objetos de la clase No es accesible por this El nivel de acceso no se modifica Es necesario inicializar un atributo estático en algún momento y una única vez Típicamente en el fichero fuente donde se define la clase Un atributo de tipo static const int se puede inicializar en la declaración DECLARACION (Foo.h) class Foo{ static int numref; //contador de objetos creados public: Foo() {numref++;} ~Foo() {numref--;} //… }; EJERCICIO ¿Salida en pantalla? DEFINICION (Foo.h/cpp) int Foo::numref = 0; //… TEST UNITARIO (*.cpp) void main(){ Foo f1, f2, f3; cout<<“creados: “<<Foo::numref<<“objetos”; } Acceso desde fuera de la clase <ID_CLASE>::<static_var>
21
Calificativo static para funciones miembro
Métodos comunes a todos los objetos de la clase No accesibles por this Solo pueden acceder a los atributos static de la clase class Foo{ static int numref; public: Foo() {numref++;} ~Foo() {numref--;} static int get_numref(){return numref;} }; int Foo::numref = 0;
22
Ejemplo: patrón singleton (objeto único)
class Singleton{ private: static Singleton* m_p; //una única instancia int a; Singleton(int a):a(a){ cout<<"llamada al constuctor"<<endl; } public: static Singleton* create_single_object(int a){ if(!m_p){m_p= new Singleton(a);} return m_p; int get(){return a;} }; Singleton* Singleton::m_p=NULL; //inicializa m_p Constructor privado Función estática miembro Solo accede al dato miembro static m_p ¡Obligatorio! EJERCICIO Implemente un test unitario para el patrón CUESTIÓN ¿Destrucción?
23
Ejemplo: encapsulador de datos globales
struct casilla_t{ int x; int y; }; class globals{ public: static double dato_double; static int dato_int; //se puede inicializar aquí static casilla_t casilla; double globals::dato_double=0.0; int globals::dato_int=0; casilla_t globals::casilla={0,0}; void main(){ globals::dato_double=10.0; globals::dato_int=0; globals::casilla.x=10; globals::casilla.y=20; }
24
Ejemplo: integración de datos globales
Implemente un programa C++ con la siguiente estructura: Datos globales: 3 con tipos double, int y casilla_t Fichero main.cpp que muestra esos datos globales en pantalla Fichero lector.cpp que lee esos datos globales
25
Índice Introducción al concepto de clase Elementos de una clase
Implementación: declaración y definición Permisos y encapsulamiento Constructores y destructores Constructor copia Inicialización de objetos miembro Creación dinámica de objetos Calificativo const para objetos Calificativo static para objetos Calificativo friend para objetos
26
Declaración de amistad: friend
El calificativo friend inhibe los niveles de permisos de una clase (desprotege su parte privada/protegida) El calificativo se coloca en la declaración de la clase Parte privada o pública, es irrelevante Es aplicable a funciones independientes, métodos y clases métodos / func. indep.: permiso de acceso individual clases: permiso de acceso a todas sus funciones miembro class A{ friend class B; }; class A{ friend int B::foo(const A&); }; REGLA GENERAL: Una función, método o clase con calificativo friend en la declaración de otra clase C tiene el mismo nivel de permiso en C que las funciones miembro de C. INTUICIÓN: La parte privada de una clase es accesible a los métodos de dicha clase y a sus amigos
27
Tipos de amistad Función independiente amiga de una clase (I)
Función miembro amiga de una clase (II) Función amiga de varias clases Todas las funciones miembro de una clase B amigas de una clase A (III) Caso II (A.h) #include "B.h" //dep. de B class A{ friend int B::foo(const A&); }; Caso I (B.h) class B{ friend int foo(const B&); }; Caso III (A.h) class A{ friend class B; }; La declaración de amistad de la clase B no requiere conocimiento de dicha clase en A (no hay dependencia)
28
Ejemplo Implemente un ejemplo de uso de una función independiente amiga de una clase y que permita acceder a su parte privada para sacar en pantalla su estado Compruebe que efectivamente la declaración de amistad se salta el nivel de protección DECLARACION (A.h) class A{ int dato; friend void print(const A& a); }; Fichero (.cpp) con visibilidad de A.h #include <iostream> #include "A.h" void print (const A& a) {cout<<"dato: “<< a.dato; }
29
Consideraciones en la relación de amistad
NO es una relación simétrica NO es una relación transitiva A amigo de B y B amigo de C no significa A amigo de C Es necesario explicitar la relación para cada pareja Evitar su uso si posible p. ej. cuando la función amiga solo contiene llamadas al interfaz (parte pública) de la clase CONSEJO: ¡CUANTOS MENOS AMIGOS MEJOR!
30
Ejercicio Implemente una clase Punto para puntos 2D que contenga todas las funcionalidades vistas hasta el momento: Constructor sin argumentos (0.0, 0.0) y constructor copia Métodos get y set para la parte privada (las coordenadas (x,y)) Método de visualización en pantalla Función independiente amiga que devuelva la distancia al origen Test unitario: Validación de todas las funcionalidades para un punto (3.0, 5.0)
31
Ejercicio-conteo de referencias
Implemente una clase String para gestionar cadenas de caracteres y que permita minimizar la copia “profunda” de su valor mediante un conteo de referencias. String a("Hello"); String b(a); String c(b); String d(c); String e(d); idealmente String s1("More effective C++"); String s2(s1);
32
Cuestiones de sintaxis (1/2)
class A{ //… }; class A a1, a2; class C{ int x; public: C(C c){x=c.x} }; class A{ //… }; void main(){ cout<<"hola mundo"; } class A{ private: int dato //… }; void foo(){ A a; a.dato=0; } class C{ int x; public: C(C& c){x=c.x} }; class A{ //… int a; int b; public: A(int d); }; class C{ static int x=10; public: C(){} }; class Punto{ //… int x; int y; public: void Punto(int x, int y); }; class C{ public: void C(){} }; class D{ static int x; public: D(){} }; D::x=10; class C{ int x; public: C()={x=5;} }; class Punto{ //… int x, y; public: Punto(int x){Punto(x, x);} Punto(int x, int y); };
33
Cuestiones de sintaxis (2/2)
class Punto(){ int x, y; public: Punto(int x, int y) {this->x=x; this->y=y;} }; Punto vector[10]; class Punto{ int x, y; public: Punto(int x=10, int y=20) {this->x=x; this->y=y;} }; Punto vector[10];
Presentaciones similares
© 2025 SlidePlayer.es Inc.
All rights reserved.