Descargar la presentación
La descarga está en progreso. Por favor, espere
Publicada porÁngel Rodríguez Redondo Modificado hace 9 años
1
Clases, Objetos y Métodos Pablo San Segundo (C-206) pablo.sansegundo@upm.es
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
Introducción al concepto de clase (1/2) Tipo de usuario para números complejos en C En C++ se encapsulan los datos con las funciones que operan sobre dichos datos en una clase Cada instancia (variable) de tipo clase se denomina objeto //C-style complex number type struct complex_t{ double i; double j; }; double modulo(complex_t c){ return(sqrt(c.i*c.i + c.j*c.j)); }; ////////////////////////// void main(){ struct complex_t micomplejo={5.0, 5.0}; printf("modulo: %f\n", modulo(micomplejo)); }
4
Introducción al concepto de clase (2/2) #include “complex.h” #include using namespace std; void main(){ Complex micomplejo(5.0, 5.0); cout<<"el modulo es:"<<micomplejo.modulo()<<endl; } Tipo (de clase) definido por el usuario
5
Í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
6
Elementos de una clase Identificador: el nombre de la clase Semejante al nombre del tipo de struct en C Un conjunto de datos miembro Un conjunto de funciones miembro Operan sobre los datos de la clase Un conjunto de permisos Niveles de acceso a los datos y funciones miembro de la clase Restringe el acceso al usuario/cliente de la clase Declaración y definición datos restringidos
7
Í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
8
Implementación en C++ de una clase (1/4) Declaración: Se define el esqueleto de la clase Prototipos de funciones miembro Datos miembro Lugar : Definición: Contiene el código que compone las funciones miembro Lugar (por defecto): DECLARACION (complex.h) class Complex{ public: double i; double j; double modulo(); }; DEFINICIÓN (complex.cpp) #include #include “complex.h” double Complex::modulo(){ return sqrt(i*i+j*j); } USUARIO/CLIENTE DE LA CLASE (.cpp) #include “complex.h” void main(){ Complex micomplejo;//objeto nuevo micomplejo.i=5.0; micomplejo.j=7.0; cout<<micomplejo.modulo()<<endl; } CUESTIÓN ¿cómo se puede proteger el acceso directo a i, j del usuario/cliente de la clase ? acceso a datos miembro diferentes ‘dentro’ y ‘fuera’ de la clase
9
Declaración de clase (2/4) class { [ ] [ ] //… } [Lista de objetos]; DECLARACION (.h) class Complex{ public: double i; double j; double modulo(); }mic1, mic2; DECLARACION (.h) class Complex{ private: double i; double j; public: void set(double i, double j); double modulo(); }mic1, mic2;
10
Definición de función miembro (3/4) Función miembro en fichero fuente :: ( ) { [código del método] } DEFINICIÓN (.cpp) #include “complex.h” double Complex::modulo(){ return sqrt(i*i+j*j); } DEFINICIÓN (.cpp) #include “complex.h” void Complex::set(double i1, double j1){ i=i1; j=j1; }
11
Resumen (4/4) Caso general Declaración de clase en un archivo cabecera (.h) Definición de métodos en un archivo fuente (.cpp) Casos particulares La declaración y definición de una clase pueden ir en un mismo archivo fuente, pero entonces complica su reutilización Se puede definir una función miembro como inline en el fichero cabecera DECLARACION (complex.h) class Complex{ public: double i; double j; double modulo(); }; DEFINICIÓN (complex.cpp) #include “complex.h” double Complex::modulo(){ return sqrt(i*i+j*j); } CLIENTE (main.cpp) #include “complex.h” void main(){ Complex micomplejo; micomplejo.i = 8.0; //… } DEFINICIÓN INLINE (complex.h) class Complex{ public: double modulo(){ return sqrt(i*i+j*j); } };
12
Í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
13
Acceso a miembros Variable objeto Accede a sus miembros mediante “.” Puntero a objeto Accede a sus miembros mediante “->” CLIENTE (main.cpp) #include “complex.h” void main(){ Complex micomplejo; double m = micomplejo.modulo(); Complex* pc = & micomplejo; m = p->modulo(); } CUESTIÓN ¿Acceso a los miembros mediante una referencia al objeto?
14
Permisos y encapsulamiento (1/3) private: miembros solo accesibles desde la propia clase (def. funciones miembro) Es el permiso por defecto Excepción: declaración de amistad public: miembros accesibles desde la propia clase y el exterior (cliente) POO: niveles de acceso permiten “encapsular” el código Los objetos se comportan autónomamente Se pueden definir funcionalidades internas “invisibles” a otros objetos Fichero: “listanum.h” #define MAX_ELEM 100 class ListaNum{ private: int nElem; int lista[MAX_ELEM]; public: void add_elem (int dato); int get_elem (int pos); int get_size(); void print(); }; CUESTIÓN Indique semejanzas y diferencias del concepto de permisos con un struct de C EJERCICIO Implemente los métodos de la clase ListaNum de manera coherente
15
Permisos y encapsulamiento (2/3) int ListaNum::get_size(){ return nElem; } int ListaNum::get_elem(int pos){ if(pos < nElem) return lista[pos]; else return -1; } void ListaNum::add_elem (int dato){ if(nElem < MAX_ELEM) lista[nElem ++]=dato; } void ListaNum::print(){ for(int i=0; i<nElem; i++) cout<<lista[i]<<" "; } //constructor! ListaNum::ListaNum(){ nElem=0; }
16
Permisos y encapsulamiento (3/3) La unidad de protección es la clase, no el objeto Cualquier función miembro puede acceder a los datos de cualquier objeto de su clase DECLARACION (complex.h) class Complex{ private: double i; double j; public: void foo(Complex& outer); }; DEFINICIÓN (complex.cpp) #include “complex.h” void Complex::foo(Complex& outer) { cout<<“mi parte real: “<<i<<endl; cout<<“parte real de outer: “<<outer.i<<endl; } CUESTIÓN Comentar el paso por referencia del argumento de la función miembro foo. ¿Qué diferencia habría con una implementación de foo mediente paso del argumento por valor?
17
Í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
18
Nociones generales de constructor Función miembro especial que garantiza que los objetos se crean en un estado previsto por el diseñador de la clase (inicializa los objetos en el momento de su creación). Su nombre es el nombre de la clase. No retorna ningún valor: su prototipo no tiene tipo de retorno. Es llamado en el momento de la creación del objeto. Debe ser público en el caso general Si el constructor es privado no se podrá crear ningún objeto de la clase. Existe un constructor por defecto Llamado si el diseñador de la clase no ha definido constructor. class Complex{ public: Complex (double i, double j); private: double i; double j; };
19
Ejemplos DECLARACION (.h) class Complex{ private: double i; double j; public: Complex(double i, double j); Complex() {i=0.0; j=0.0;} //… }; DEFINICIÓN (.cpp) Complex::Complex(double i, double j){ Complex::i = i; Complex::j = j; } DECLARACION/DEF. EN LINEA (.h) class Complex{ private: double i; double j; public: Complex(double i, double j){ Complex::i = i; Complex::j = j; } }; Constructor sobrecargado inline sin argumentos CUESTIÓN Implemente un programa que inicialice un objeto complejo en (0.0, 0.0) mediante un constructor sin argumentos, y luego lo use para encontrar el módulo de (3.0,4.0). Nota: modifique la clase Complex adecuadamente
20
Puntero this this: puntero implícito asociado a cada objeto (instancia) de la clase APLICACIÓN AL CASO DEL CONSTRUCTOR (.cpp) Complex::Complex(double i, double j){ this->i=i; this->j=j; }
21
Sintaxis de inicialización: ‘()’ Tipos base Objeto Definición de un constructor (*.cpp) Definición de constructor inline (*.h) int a(4);//equivale int a=4 float f(5.0);//equivale int f=5.0 Complex micomplejo (4.0, 5.0); //llama al constructor apropiado Complex::Complex(): i(4.0) {double j=5.0;} Complex::Complex(): i(4.0), j(5.0) {} Complex(): i(4.0), j(5,0) {} Complex micomplejo; //llama al const. sin arg. o pred. listas de inicialización
22
Destructor de una clase Complemento del constructor Es llamado justo antes de que el objeto deja de existir en memoria Ejemplo: objeto automático al finalizar su bloque Para objetos globales (o estáticos) su vida coincide con la de ejecución del programa El destructor será llamado al finalizar la ejecución del programa El destructor es único para cada clase y no puede ser sobrecargado No tiene valor de retorno (al igual que el constructor) No tiene argumentos SINTAXIS (.cpp) ::~ () {…} CUESTIÓN Implemente un programa que compruebe la llamada al destructor de una clase
23
Ejemplo (I) DECLARACION(complex.h) class Complex{ private: double i; double j; public: Complex(double i, double j); Complex(); ~Complex(); //… }; DEFINICIÓN (complex.cpp) Complex::~Complex(){ cout<<“Llamada al destructor”<<endl; } Complex::Complex(){ cout<<“Llamada al constructor”<<endl; i=0.0; j=0.0; } TEST UNITARIO (test.cpp) void main(){ Complex micomplejo; Complex micomplejo1(5.0, 6.0); double mod = micomplejo.modulo(); } CUESTIÓN II ¿Valor de mod? ¿Salida por pantalla? CUESTIÓN I ¿Sintaxis alternativas? CUESTIÓN III ¿Qué ocurre si se elimina el destructor?
24
Ejemplo (II) Para la clase Complex del ejercicio anterior: CASO A int foo(){ Complex micomplejo; return 0; } void main(){ for(int i=0; i<5; i++){ foo(); } CASO B int foo(){ static Complex micomplejo; return 0; } void main(){ for(int i=0; i<5; i++){ foo(); } DEFINICIONES RELACIONADAS Complex::~Complex(){ cout<<“Llamada al destructor”<<endl; } Complex::Complex(){ cout<<“Llamada al constructor sin argumentos”<<endl; i=0.0; j=0.0; } CUESTIÓN I ¿Salida en pantalla para el caso A? Objeto automático Objeto estático CUESTIÓN II ¿Salida en pantalla para el caso B?
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 Creación dinámica de objetos Calificativo const para objetos Calificativo static para objetos Calificativo friend para objetos
26
Nociones generales de constructor copia Permite inicializar un objeto con otro objeto de su misma clase Existe un constructor copia por defecto Hace una copia simple del estado del objeto Esta copia simple será suficiente mientras no existan datos miembro que empleen asignación dinámica de memoria Fichero fuente (foo.cpp) class Foo { int a; int b; Foo(const Foo&) {//…} }; void main (){ Foo mifoo; Foo mifoo_1(mifoo); //ó Foo mifoo_1=mifoo; } CUESTIONES Comente acerca de la corrección del código I.¿compila? II.¿produce error en tiempo de ejecución?
27
Constructor copia: sintaxis Definición inline-A (complex.h) class Complex { private: double a, b; public: Complex(const Complex& micomp): a(micomp.a), b(micomp.b) {} }; :: (const & ) ; Definición convencional-C (complex.cpp) Complex::Complex(const Complex& micomp){ a = micomp.a; b = micomp.b; } Definición inline-B (complex.h) class Complex { private: double a, b; public: Complex(const Complex& micomp){ a = micomp.a; b = micomp.b; } };
28
Ejemplo (I) class Foo{ int vector[5]; public: Foo(){cout<<"llamada al constructor sin argumentos"<<endl;} Foo(const Foo& c){cout<<"llamada al constructor copia"<<endl;} //… }; CLIENTE de Foo (.cpp) void main(){ //… Foo f1; Foo f2 = f1; //… } CUESTIÓN ¿Salida en pantalla?
29
Ejemplo (II) class Foo{ public: int vector[2]; Foo(){cout<<"llamada al constructor sin parametros"<<endl;} Foo(const Foo& c){cout<<"llamada al constructor copia"<<endl;} void print() { for(int i=0; i<2; i++){cout<<vector[i]<<" ";} } //… }; TEST UNITARIO (.cpp) void main(){ //… Foo f1; f1.vector[0]=0; f1.vector[1]=1; Foo f2 = f1; f2.print(); //… } CUESTIÓN ¿Salida en pantalla? EJERCICIO Implemente una clase para poder gestionar un vector de dimensión variable (con constructor copia) ¿Se observa alguna diferencia en la construcción / destrucción?
30
Solución parcial-prototipos Foo::Foo (int n); Foo::Foo (const Foo& ); void Foo::print (); void Foo::push_back (int dato); ~Foo::Foo(); TEST UNITARIO (.cpp) void main(){ Foo f1(5); f1.push_back(20); f1.push_back(30); Foo f2(f1); f2.print(); }
31
Ejemplo (III)- paso de un objeto por valor En general se llamará al constructor copia cuando: Se inicializa un objeto con otro del mismo tipo Se pasa un objeto por valor a una función (objeto temporal) DECLARACION (foo.h) class Foo{ //… Foo(const Foo& c){cout<<"llamada al constructor copia"<<endl;} }; int foofunc(Foo f){ return 0;}//función independiente TEST UNITARIO-CLIENTE (.cpp) void main(){ Foo f1; foofunc(f1);//paso objeto por valor }; CUESTIÓN ¿Salida en pantalla?
32
Í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
33
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 clase 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?
34
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;} }; CUESTIÓN ¿Diferencias entre el caso A y el caso B? CASO-B #include “B.h” class A{ B b; public: A(int dato):b(dato){} };
35
Ejemplo 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?
36
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);//constructor }; 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?
37
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; public: 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;} }; USUARIO (.cpp) void main(){ A a; A a1(a); } CUESTIÓN ¿salida en pantalla? REGLA Definido el constructor copia del contenedor, éste tiene TODA la responsabilidad de las copias de sus objetos miembro
38
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); }
39
Í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
40
void main(){ int n=10; Complex * pcom = new Complex[n]; delete [] pcom; } ARRAY DE OBJETOS void main(){ Complex * pcom = new Complex(5.0, 6.0); delete pcom; } OBJETO SIMPLE Llama al constructor sin argumentos en los 10 objetos 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 Llama al destructor antes de liberar memoria Llama al destructor antes de liberar memoria para cada objeto CUESTIÓN Comparación con malloc y free para objetos
41
Í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
42
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 { cout<<i<<“ “<<j<<endl; } }; “CONST” DEFINICION (.cpp) void Complex::print() const { cout<<i<<“ “<<j<<endl; } };
43
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). Incluidos 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 sa;}; private: s_t* a; public: Foo(s_t* a_outer):a(a_outer){} void print() const; }; DEFINICION (Foo.cpp) void Foo::print() const{ a->sa=20; //constness? }
44
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. Solo toman valores en la llamada al constructor Hay que usar obligatoriamente la lista de inicialización 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 Sintaxis “:” obligatoria
45
Calificativo const en el paso por referencia Impide que la referencia pasada pueda usarse como un l- value Caso de ser una referencia a un objeto, solo es posible llamar a la parte de su interfaz público declarado 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 }
46
Í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
47
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?
48
DEFINICION (Foo.h/cpp) int Foo::numref = 0; //… 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 base static const se puede inicializar en la declaración DECLARACION (Foo.h) class Foo{ static int numref; //contador de objetos creados public: Foo() {numref++;} ~Foo() {numref--;} //… }; TEST UNITARIO (*.cpp) void main(){ Foo f1, f2, f3; cout<<“creados: “<<Foo::numref<<“objetos”; } Acceso desde fuera de la clase :: EJERCICIO ¿Salida en pantalla?
49
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;
50
Ejemplo: patrón singleton 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 Función estática miembro Solo accede al dato miembro static m_p ¡Obligatorio! Constructor privado EJERCICIO Implemente un test unitario para el patrón CUESTIÓN ¿Destrucción?
51
Í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
52
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 REGLA GENERAL: Una función, método o clase con calificativo friend en la declaración de otra clase tiene el mismo nivel de permiso que las funciones miembro de dicha clase. INTUICIÓN: La parte privada de una clase es accesible a los métodos de dicha clase y a sus amigos class A{ friend int B::foo(const A&); }; class A{ friend class B; };
53
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 I (B.h) class B{ friend int foo(const B&); }; Caso II (A.h) #include “B.h” //dep. de B class A{ friend int B::foo(const A&); }; 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
54
Ejercicio 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 #include “A.h” void print (const A& a) {cout<<“dato: “<< a.dato; }
55
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 de la clase Consejo: ¡Cuántos menos buenos amigos mejor !
56
Ejercicio Implemente una clase Punto para puntos 2D que contenga todas las funcionalidades vistas hasta el momento: A)Constructor sin argumentos (0.0, 0.0) y constructor copia B)Métodos get y set para la parte privada (las coordenadas (x,y)) C)Método de visualización en pantalla D)Función independiente amiga que devuelva la distancia al origen E)Test unitario: Validación de todas las funcionalidades para un punto (3.0, 5.0)
57
Cuestiones de sintaxis (1/2) class A{ //… }; class A a1, a2; class A{ private: int dato //… }; void foo(){ A a; a.dato=0; } class C{ public: void C(){} }; class C{ int x; public: C()={x=5;} }; class C{ int x; public: C(C c){x=c.x} }; class C{ int x; public: C(C& c){x=c.x} }; class C{ static int x=10; public: C(){} }; class D{ static int x; public: D(){} }; D::x=10; class A{ //… }; void main(){ cout<<“hola mundo”; } class A{ //… int a; int b; public: A(int d); }; class Punto{ //… int x; int y; public: void Punto(int x, int y); }; class Punto{ //… int x, y; public: Punto(int x){Punto(x, x);} Punto(int x, int y); };
58
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.