Vous êtes sur la page 1sur 8

El concepto de clase[editar]

Vase tambin: Clase (informtica)

Los objetos en C++ son abstrados mediante una clase. Segn el paradigma de la
programacin orientada a objetos un objeto consta de:

1. Identidad, que lo diferencia de otros objetos (Nombre que llevar la clase a la que
pertenece dicho objeto).
2. Mtodos o funciones miembro
3. Atributos o variables miembro
Un ejemplo de clase que podemos tomar es la clase perro. Cada perro comparte unas
caractersticas (atributos). Su nmero de patas, el color de su pelaje o su tamao son
algunos de sus atributos. Las funciones que lo hagan ladrar, cambiar su comportamiento...
esas son las funciones de la clase.
Este es otro ejemplo de una clase:

class Punto
{
//por omisin, los miembros son 'private' para que solo se puedan
modificar desde la propia clase.
private:
// Variable miembro privada
int id;
protected:
// Variables miembro protegidas
int x;
int y;
public:
// Constructor
Punto();
// Destructor
~Punto();
// Funciones miembro o mtodos
int ObtenerX();
int ObtenerY();
};

Constructores[editar]
Vase tambin: Constructor (informtica)

Son unos mtodos especiales que se ejecutan automticamente al crear un objeto de la


clase. En su declaracin no se especifica el tipo de dato que devuelven, y poseen el
mismo nombre que la clase a la que pertenecen. Al igual que otros mtodos, puede haber
varios constructores sobrecargados, aunque no pueden existir constructores virtuales.
Como caracterstica especial a la hora de implementar un constructor, justo despus de la
declaracin de los parmetros, se encuentra lo que se llama "lista de inicializadores". Su
objetivo es llamar a los constructores de los atributos que conforman el objeto a construir.
Cabe destacar que no es necesario declarar un constructor al igual que un destructor,
pues el compilador lo puede hacer, aunque no es la mejor forma de programar.
Tomando el ejemplo de la Clase Punto, si deseamos que cada vez que se cree un objeto
de esta clase las coordenadas del punto sean igual a cero podemos agregar un
constructor como se muestra a continuacin:

class Punto
{
public:

float x; // Coordenadas del punto


float y;

// Constructor
Punto() : x(0), y(0){ // Inicializamos las variables "x" e "y"
}
};

// Main para demostrar el funcionamiento de la clase

# include <iostream> // Esto nos permite utilizar "cout"

using namespace std;

int main () {
Punto MiPunto; // creamos un elemento de la clase Punto
llamado MiPunto

cout << "Coordenada X: " << MiPunto.x << endl; // mostramos el


valor acumulado en la variable x
cout << "Coordenada Y: " << MiPunto.y << endl; // mostramos el
valor acumulado en la variable y
getchar(); // le indicamos al programa que espere al buffer de
entrada (detenerse)
return 0;
}

Si compilamos y ejecutamos el anterior programa, obtenemos una salida que debe ser
similar a la siguiente:
Coordenada X: 0 Coordenada Y: 0
Existen varios tipos de constructores en C++:

1. Constructor predeterminado. Es el constructor que no recibe ningn parmetro


en la funcin. Si no se definiera ningn constructor, el sistema proporcionara uno
predeterminado. Es necesario para la construccin de estructuras y contenedores
de la STL.
2. Constructor de copia. Es un constructor que recibe un objeto de la misma clase,
y realiza una copia de los atributos del mismo. Al igual que el predeterminado, si
no se define, el sistema proporciona uno.
3. Constructor de conversin. Este constructor, recibe como nico parmetro, un
objeto o variable de otro tipo distinto al suyo propio. Es decir, convierte un objeto
de un tipo determinado a otro objeto del tipo que estamos generando.
Constructores + Memoria heap Un objeto creado de la forma que se vio hasta ahora, es
un objeto que vive dentro del scope(las llaves { }) en el que fue creado. Para que un objeto
pueda seguir viviendo cuando se saque del scope en el que se cre, se lo debe crear en
memoria heap. Para esto, se utiliza el operador new, el cual asigna memoria para
almacenar al objeto creado, y adems llama a su constructor(por lo que se le pueden
enviar parmetros). El operador new se utiliza de la siguiente manera:

int main() {
Punto *unPunto = new Punto(); //esto llama al constructor que se
describe ms arriba
delete unPunto; //no hay que olvidarse de liberar la
memoria ocupada por el objeto(ver la seccin destructores, ms abajo)
return 0;
}

Adems, con el operador new[] se pueden crear arrays (colecciones o listas ordenadas) de
tamao dinmico:

Punto *asignar(int cuantos) {


return new Punto[cuantos]; //asigna un array de 'cuantos' puntos(se
llama el constructor que se muestra ms arriba), y se retorna.
}

Destructores[editar]
Vase tambin: Destructor (informtica)

Los destructores son funciones miembro especiales llamadas automticamente en la


ejecucin del programa, y por tanto no tienen por qu ser llamadas explcitamente por
el programador. Sus principales cometidos son:

Liberar los recursos computacionales que el objeto de dicha clase haya adquirido en
tiempo de ejecucin al expirar este.
Quitar los vnculos que pudiesen tener otros recursos u objetos con este.
Los destructores son invocados automticamente al alcanzar el flujo del programa el fin del
mbito en el que est declarado el objeto. El nico caso en el que se debe invocar
explcitamente al destructor de un objeto, es cuando este fue creado mediante el
operador new, es decir, que este vive en memoria heap, y no en la pila de ejecucin del
programa. La invocacin del destructor de un objeto que vive en heap se realiza a travs
del operador delete o delete[] para arrays. Ejemplo:

int main() {
int *unEntero = new int(12); //asignamos un entero en
memoria heap con el valor 12
int *arrayDeEnteros = new int[25]; //asignamos memoria para 25
enteros(no estn inicializados)
delete unEntero; //liberamos la memoria que
ocupaba unEntero
delete[] arrayDeEnteros; //liberamos la memoria ocupada
por arrayDeEnteros
return 0;
}

Si no se utilizara el operador delete y delete[] en ese caso, la memoria ocupada por


unEntero y arrayDeEnteros respectivamente, quedara ocupada sin sentido. Cuando una
porcin de memoria queda ocupada por una variable que ya no se utiliza, y no hay forma
de acceder a ella, se denomina un 'memory leak'. En aplicaciones grandes, si ocurren
muchos memory leaks, el programa puede terminar ocupando bastante ms memoria
RAM de la que debera, lo que no es para nada conveniente. Es por esto, que el manejo
de memoria heap debe usarse conscientemente.
Existen dos tipos de destructores pueden ser pblicos o privados, segn si se declaran:

Si es pblico se llama desde cualquier parte del programa para destruir el objeto.
Si es privado no se permite la destruccin del objeto por el usuario.
El uso de destructores es clave en el concepto de Adquirir Recursos es Inicializar.

Funciones miembro[editar]
Funcin miembro es aquella que est declarada en mbito de clase. Son similares a las
funciones habituales, con la salvedad de que el compilador realizara el proceso
de Decoracin de nombre (Name Mangling en ingls): Cambiar el nombre de la funcin
aadiendo un identificador de la clase en la que est declarada, pudiendo incluir
caracteres especiales o identificadores numricos. Este proceso es invisible al
programador. Adems, las funciones miembro reciben implcitamente un parmetro
adicional: El puntero this, que referencia al objeto que ejecuta la funcin.
Las funciones miembro se invocan accediendo primero al objeto al cual refieren, con la
sintaxis: myobject.mymemberfunction(), esto es un claro ejemplo de una funcin
miembro.
Caso especial es el de las funciones miembro estticas. A pesar de que son declaradas
dentro de la clase, con el uso de la palabra clave static no recibirn el puntero this.
Gracias a esto no es necesario crear ninguna instancia de la clase para llamar a esta
funcin, sin embargo, solo se podr acceder a los miembros estticos de la clase dado que
estos no estn asociados al objeto sino al tipo. La sintaxis para llamar a esta funcin
esttica es mytype::mystaticmember().

Plantillas[editar]
Las plantillas son el mecanismo de C++ para implantar el paradigma de la programacin
genrica. Permiten que una clase o funcin trabaje con tipos de datos abstractos,
especificndose ms adelante cuales son los que se quieren usar. Por ejemplo, es posible
construir un vector genrico que pueda contener cualquier tipo de estructura de datos. De
esta forma se pueden declarar objetos de la clase de este vector que contengan enteros,
flotantes, polgonos, figuras, fichas de personal, etc.
La declaracin de una plantilla se realiza anteponiendo la declaracin template
<typename A,....> a la declaracin de la estructura (clase, estructura o funcin)
deseado.
Por ejemplo:

template <typename T>


T max(const T &x, const T &y) {
return (x > y) ? x : y; //si x > y, retorna x, sino retorna y
}

La funcin max() es un ejemplo de programacin genrica, y dados dos parmetros de un


tipo T (que puede ser int, long, float, double, etc.) devolver el mayor de ellos
(usando el operador >). Al ejecutar la funcin con parmetros de un cierto tipo, el
compilador intentar "calzar" la plantilla a ese tipo de datos, o bien generar un mensaje
de error si fracasa en ese proceso.
Especializacin[editar]
El siguiente ejemplo:

template <typename A> int myfunction(A a);

crea una plantilla bajo la cual pueden ser definidas en el cdigo de cabecera cualesquiera
funciones especializadas para un tipo de datos como int myfunction(int), int
myfunction(std::string), int myfunction(bool), etctera:

int myfunction (int a) {


return a + 5;
};

int myfunction (std::string a) {


return -a.size();
};

int myfunction (bool a) {


return (a & rand()); //Si a es Verdadero, devuelve un numero
aleatorio; en caso contrario devuelve 0
};

Cada una de estas funciones tiene su propia definicin (cuerpo). Cada cuerpo diferente, no
equivalente ("no convertible") corresponde a una especializacin. Si una de estas
funciones no fuera definida, el compilador tratar de aplicar las conversiones de tipos de
datos que le fuesen permitidas para "calzar" una de las plantillas, o generar un mensaje
de error si fracasa en ese proceso.
Todas las definiciones habilitadas de una plantilla deben estar disponibles al momento de
la compilacin, por lo cual no es posible actualmente "compilar" una plantilla como archivo
de objeto, sino simplemente compilar especializaciones de la plantilla. Por lo tanto, las
plantillas se distribuyen junto con el cdigo fuente de la aplicacin. En otras palabras, no
es posible compilar la plantilla std::vector< > a cdigo objeto, pero s es posible, por
ejemplo, compilar un tipo de datos std::vector<std::string>.

Clases abstractas[editar]
En C++ es posible definir clases abstractas. Una clase abstracta, o clase base abstracta
(ABC), es una que est diseada solo como clase padre de las cuales se deben derivar
clases hijas. Una clase abstracta se usa para representar aquellas entidades o mtodos
que despus se implementarn en las clases derivadas, pero la clase abstracta en s no
contiene ninguna implementacin -- solamente representa los mtodos que se deben
implementar. Por ello, no es posible instanciar una clase abstracta, pero s una clase
concreta que implemente los mtodos definidos en ella.
Las clases abstractas son tiles para definir interfaces, es decir, un conjunto de mtodos
que definen el comportamiento de un mdulo determinado. Estas definiciones pueden
utilizarse sin tener en cuenta la implementacin que se har de ellos.
En C++ los mtodos de las clases abstractas se definen como funciones virtuales puras.

class Abstracta
{
public:
virtual int metodo() = 0;
}

class ConcretaA : public Abstracta


{
public:
int metodo()
{
//haz algo
return foo () + 2;
}
};

class ConcretaB : public Abstracta


{
public:
int metodo()
{
//otra implementacin
return baz () - 5;
}
};

En el ejemplo, la clase ConcretaA es una implementacin de la clase Abstracta, y la


clase ConcretaB es otra implementacin. Debe notarse que el = 0 es la notacin que
emplea C++ para definir funciones virtuales puras.

Espacios de nombres[editar]
Una adicin a las caractersticas de C son los espacios de nombre (namespace en
ingls), los cuales pueden describirse como reas virtuales bajo las cuales ciertos nombres
de variable o tipos tienen validez. Esto permite evitar las ocurrencias de conflictos entre
nombres de funciones, variables o clases.
El ejemplo ms conocido en C++ es el espacio de nombres std::, el cual almacena todas
las definiciones nuevas en C++ que difieren de C (algunas estructuras y funciones), as
como las funcionalidades propias de C++ (streams) y los componentes de la biblioteca
STL.
Por ejemplo:

# include <iostream>
// Las funciones en esta cabecera existen dentro del espacio de
nombres std::

namespace mi_paquete{
int mi_valor;
};

int main()
{
int mi_valor = 3;
mi_paquete::mi_valor = 4;

std::cout << mi_valor << '\n'; // imprime '3'


std::cout << mi_paquete::mi_valor << '\n'; // imprime '4'

return 0;
}

Como puede verse, las invocaciones directas a mi_valor darn acceso solamente a la
variable descrita localmente; para acceder a la variable del espacio de
nombres mi_paquete es necesario acceder especficamente el espacio de nombres. Un
atajo recomendado para programas sencillos es la directiva using namespace, que
permite acceder a los nombres de variables del paquete deseado en forma directa,
siempre y cuando no se produzca alguna ambigedad o conflicto de nombres.

Herencia[editar]
Existen varios tipos de herencia entre clases en el lenguaje de programacin C++. Estos
son:
Herencia simple[editar]
La herencia en C++ es un mecanismo de abstraccin creado para poder facilitar y mejorar
el diseo de las clases de un programa. Con ella se pueden crear nuevas clases a partir
de clases ya hechas, siempre y cuando tengan un tipo de relacin especial.
En la herencia, las clases derivadas "heredan" los datos y las funciones miembro de las
clases base, pudiendo las clases derivadas redefinir estos comportamientos (polimorfismo)
y aadir comportamientos nuevos propios de las clases derivadas. Para no romper el
principio de encapsulamiento (ocultar datos cuyo conocimiento no es necesario para el uso
de las clases), se proporciona un nuevo modo de visibilidad de los datos/funciones:
"protected". Cualquier cosa que tenga visibilidad protected se comportar como pblica en
la clase Base y en las que componen la jerarqua de herencia, y como privada en las
clases que NO sean de la jerarqua de la herencia.
Antes de utilizar la herencia, nos tenemos que hacer una pregunta, y si tiene sentido,
podemos intentar usar esta jerarqua: Si la frase <claseB> ES-UN <claseA> tiene sentido,
entonces estamos ante un posible caso de herencia donde clase A ser la clase base y
clase B la derivada.
Ejemplo: clases Barco, Acorazado, Carguero, etc. Un Acorazado ES-UN Barco, un
Carguero ES-UN Barco, un Trasatlntico ES-UN Barco, etc.
En este ejemplo tendramos las cosas generales de un Barco (en C++)

class Barco {
protected:
char* nombre;
float peso;
public:
//Constructores y dems funciones bsicas de barco
};

y ahora las caractersticas de las clases derivadas, podran (a la vez que heredan las de
barco) aadir cosas propias del subtipo de barco que vamos a crear, por ejemplo:

class Carguero: public Barco { // Esta es la manera de especificar que


hereda de Barco
private:
float carga;
//El resto de cosas
};

class Acorazado: public Barco {


private:
int numeroArmas;
int Soldados;
// El resto de cosas
};

Por ltimo, hay que mencionar que existen 3 clases de herencia que se diferencian en el
modo de manejar la visibilidad de los componentes de la clase resultante:

Herencia pblica (class Derivada: public Base ): Con este tipo de herencia se respetan
los comportamientos originales de las visibilidades de la clase Base en la clase
Derivada.
Herencia privada (clase Derivada: private Base): Con este tipo de herencia todo
componente de la clase Base, ser privado en la clase Derivada (las propiedades
heredadas sern privadas aunque estas sean pblicas en la clase Base)
Herencia protegida (clase Derivada: protected Base): Con este tipo de herencia, todo
componente pblico y protegido de la clase Base, ser protegido en la clase Derivada,
y los componentes privados, siguen siendo privados.

Vous aimerez peut-être aussi