Clases en C++ - Alemansistem

Anuncio
Clases en C++
Universidad de Carabobo
Facultad Experimental de Ciencias y Tecnología
Algoritmos y Programación II
Enero de 2005
1.
Definición de Clases
Cada clase contiene :
•
•
datos (datos miembro o campos), los cuales especifican las propiedades de los
objetos.
funciones (funciones miembro o métodos), mediante los cuales se modela su
comportamiento y las acciones que puede realizar.
Un ejemplo de esto se puede apreciar en el siguiente fragmento de código:
1
2
3
4
5
6
// Declaración de una clase
class MiClase
{
// Declaración de datos miembro
// Declaración de métodos
};
En la declaración de una clase, para cada dato miembro, debe especificarse
mediante los modificadores de acceso el ámbito desde el cual puede accederse a dicho
miembro. Éstos son:
•
•
•
private: Sólo se permite su acceso desde los métodos de la clase.
public: Se permite su acceso desde cualquier punto que pueda usar la clase. Un
dato público es accesible desde cualquier objeto de la clase.
protected: Se permite su uso en los métodos de la clase y en los de las clases
derivadas mediante herencia.
Un ejemplo de esto se puede apreciar en el siguiente fragmento de código:
1
2
3
4
5
class Triangulo
{
private:
float cat_opuesto;
float cat_adyacente;
float hipotenusa;
6
7
8
9
2.
// Declaración de métodos
};
Constructores y Destructores
Características de los constructores:
•
•
•
•
•
•
Cuando se crea un objeto de una clase siempre se llama automáticamente a un
constructor.
Se emplea para iniciar los objetos de una clase.
Es particularmente útil para reservar, si es necesario, memoria para ciertos campos
del objeto.
Pueden haber varios constructores para una clase.
Un constructor tiene el mismo nombre que la clase en la que está declarado y no
devuelve nada. OJO: NO es una función void.
Cuando no se define ningún constructor en una clase, el compilador crea un
constructor por defecto, sin argumentos, que inicia los datos miembros a cero.
Características de los destructores:
•
•
•
•
•
Sólo hay un destructor para una clase.
Cuando un objeto deja de existir siempre se llama automáticamente al destructor.
Un destructor tiene el mismo nombre de la clase, precedido por el carácter “~”.
El destructor no admite parámetros ni devuelve ningún valor. OJO: NO es una
función void.
Si no se especifica, el compilador proporciona un destructor por defecto. Su
implementación tiene sentido sólo cuando el constructor ha reservado memoria
dinámicamente.
Un ejemplo de esto se puede apreciar en el siguiente fragmento de código:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MiClase
{
public:
int *arreglo;
// Constructor
MiClase ()
{
arreglo = new int[10];
}
// Destructor
~MiClase ()
{
delete [] arreglo;
}
15
16
17
18
19
3.
};
Métodos
Características de la declaración de los métodos:
•
•
•
•
Se declaran como cua lquier función en C++.
Se especifican los prototipos de los métodos en la declaración de la clase. Su
implementación puede ser dentro de la declaración de la clase o en un archivo .cpp
Es usual disponer de métodos públicos que modifican y/o leen el valor de los datos
privados.
Pueden definirse funciones privadas que pueden ser de utilidad (funciones
auxiliares) para las funciones públicas.
Como estilo de programación y organización, se recomienda tener un archivo para
la declaración de la clase y otro para la implementación. Por ejemplo:
triangulo.h (archivo que contiene la declaración de la clase Triangulo)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef triangulo_h
#define triangulo_h
class Triangulo
{
private:
float cat_opuesto;
float cat_adyacente;
float hipotenusa;
public:
// Constructor de la clase
Triangulo();
// Métodos de inspección
float VerOpu();
float VerAdy();
float VerHip();
void MostrarTriangulo();
// Métodos de modificación
void ModOpu(float valor);
void ModAdy(float valor);
void ModHip(float valor);
void ModificarTriangulo(float ady, float op,
float hip);
26
27
28
29
};
#endif
triangulo.cpp (archivo que contiene la implementación de la clase Triangulo)
1
2
3
4
5
6
#include <iostream>
#include “triangulo.h”
using namespace std;
// Constructor de la clase
Triangulo::Triangulo()
8 {
9
this->cat_opuesto = 0;
10
cat_adyacente = 0;
11
hipotenusa = 0;
12 }
7
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Métodos de inspección
float Triangulo::VerOpu()
{
return cat_opuesto;
}
float Triangulo::VerAdy()
{
return cat_adyacente;
}
float Triangulo::VerHip()
{
return hipotenusa;
}
void Triangulo::MostrarTriangulo()
{
cout << "Cateto Opuesto: " << VerOpu() << endl;
cout << "Cateto Adyacente: " << VerAdy() << endl;
cout << "Hipotenusa: " << VerHip() << endl;
}
// Métodos de modificación
void Triangulo::ModOpu(float valor)
{
cat_opuesto = valor;
}
void Triangulo::ModAdy(float valor)
44
{
cat_adyacente = valor;
45
46
47
}
48
void Triangulo::ModHip(float valor)
{
hipotenusa = valor;
}
49
50
51
52
53
54
55
56
57
58
59
void Triangulo::ModificarTriangulo(float ady,
float op, float hip)
{
ModOpu(op);
ModAdy(ady);
ModHip(hip);
}
NOTA: El apuntador this es una variable predefinida en todas las funciones o
métodos miembro de una clase. Contiene la dirección del objeto concreto de la clase sobre
la cual se está aplicando la función u operador miembro. Al ser apuntador, el acceso a los
miembros del objeto se realizará con el operador flecha (->).
4.
Instanciación
Un objeto se puede crear de dos formas:
•
Estática (el objeto existe mientras no se pierda alcance sobre él).
Sinaxis:
•
Nombre_de_clase variable_del_objeto;
Dinámica (el objeto se crea en memoria dinámica, y existe mientras no sea
eliminado explícitamente de ésta).
Sintaxis:
Nombre_de_clase *apuntador_al_objeto;
apuntador_al_objeto = new Nombre_de_clase;
Un ejemplo de esto se puede apreciar en el siguiente fragmento de código:
1
2
3
4
5
6
7
8
9
void main ()
{
// Instanciación estática
Triangulo a;
// Instanciación dinámica
Triangulo *b;
b = new Triangulo;
...
10
11
delete b;
12
13
5.
}
Paso de Mensajes
Es la forma de comunicación entre dos o más objetos (instancias), de clases
similares o diferentes, por medio de operaciones. Un ejemplo de esto se puede apreciar en
el siguiente fragmento de código:
1
2
#include <iostream>
3
class A
{
private:
...
4
5
6
7
public:
int Op1() { ... }
8
9
10
11
};
12
class B
{
public:
int x;
13
14
15
16
int Op2(A obj) { return (x + obj.Op1()); }
17
18
19
};
20
void main ()
{
A obj1;
B obj2;
21
22
23
24
25
26
...
27
28
29
obj2.x = 100;
// Paso de mensaje
cout << obj2.Op2(obj1);
30
31
}
Observe el siguiente ejemplo que extiende a la clase Triangulo:
1
2
3
4
5
#include <iostream>
#include “triangulo.h”
Triangulo::Copiar(Triangulo t)
{
cat_opuesto = t.VerOpu();
cat_adyacente = t.VerAdy();
hipotenusa = t.VerHip();
6
7
8
9
10
11
12
13
14
}
void main ()
{
Triangulo t1, t2;
cout << “Triangulo t1” << endl;
t1.MostrarTriangulo();
t1.ModOpu(3.3);
t1.ModAdy(5.0);
t1.ModHip(7.0);
cout << “Triangulo t1 modificado” << endl;
t1.MostrarTriangulo();
t2.ModificarTriangulo(1.0, 1.0, 1.0);
15
16
17
18
19
20
21
22
23
24
// Paso de mensaje
t1.Copiar(t2);
25
26
cout << “Triangulo t1 copiado de t2” << endl;
t1.MostrarTriangulo();
27
28
29
6.
}
Herencia
La herencia es una forma de reutilización del software, en la cual se crean clases
nuevas a partir de clases existentes, mediante la absorción de sus atributos y
comportamientos, y enriqueciendo éstos con las capacidades que las clases nuevas
requieren. Las clases nuevas se denominan clases derivadas, en donde cada clase derivada
se convierte en candidata a clase base para alguna clase futura. Existen tres tipos de
herencia: pública, privada y protegida.
Sintaxis
class nombre_clase_derivada : <tipo_herencia> nombre_clase_base
{
...
};
Un ejemplo de esto se puede apreciar en el siguiente fragmento de código:
1
2
3
4
5
6
class Isosceles : public Triangulo
{
private:
int color;
public:
// Constructor de la clase
Isosceles(float catetos, float hip)
{
cat_opuesto = catetos;
cat_adyacente = catetos;
hipotenusa = hip;
}
7
8
9
10
11
12
13
14
15
// Métodos de inspección
float VerCatetos()
{
return cat_opuesto;
}
int VerColor()
{
return color;
}
16
17
18
19
20
21
22
23
24
25
// Métodos de modificación
void ModCatetos(float valor)
{
cat_opuesto = valor;
cat_adyacente = valor;
}
void ModColor(int valor)
{
color = valor;
}
26
27
28
29
30
31
32
33
34
35
};
NOTA: Si la clase base posee un único constructor que recibe unos parámetros,
entonces el encabezado del constructor de la clase derivada debe invocar al constructor de
la clase base con los parámetros requeridos. Un ejemplo de esto se puede apreciar en el
siguiente fragmento de código:
1
2
3
4
5
class A
{
private:
...
public:
A(int x, int y) { ... }
...
6
7
8
9
10
11
12
13
};
class B : public A
{
private:
int z;
14
15
public:
B(int x, int y, int z) : A(x,y)
{
this->z = z;
}
...
16
17
18
19
20
21
22
};
Descargar