Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO Pensar en C++ (Volumen 1) - Grupo ARCO

arco.esi.uclm.es
from arco.esi.uclm.es More from this publisher
13.01.2015 Views

✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 390 — #428 ✐ Capítulo 13. Creación dinámica de objetos La forma de reemplazar el manejador de new-handler por defecto consiste en incluir el archivo new.h y hacer una llamada a la función set_new_handler() con la dirección de la función que se desea instalar: //: C13:NewHandler.cpp // Changing the new-handler #include #include #include using namespace std; int count = 0; void out_of_memory() { cerr

✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 391 — #429 ✐ 13.3. new y delete para vectores re. Frecuentemente la razón para cambiar el asignador es la eficiencia; puede que se necesite crear y destruir tantos objetos de la misma clase que lo haga ineficaz en términos de velocidad: un cuello de botella. En C++ es posible sobrecargar new y d- elete para implementar un esquema particular más adecuado que permita manejar situaciones como ésta. Otra cuestión es la fragmentación del montículo. Cuando los objetos tienen tamaños diferentes es posible llegar a dividir de tal modo el área de memoria libre que se vuelva inútil. Es decir, el espacio puede estar disponible, pero debido al nivel de fragmentación alcanzado, no exista ningún bloque del tamaño requerido. Es posible asegurarse de que esto no llegue a ocurrir mediante la creación de un asignador para una clase específica. En los sistemas de tiempo real y en los sistemas integrados, suele ser necesario que los programas funcionen por largo tiempo con recursos muy limitados. Tales sistemas pueden incluso requerir que cada asignación tome siempre la misma cantidad de tiempo, y que no esté permitida la fragmentación ni el agotamiento en el área dinámica. La solución a este problema consiste en utilizar un asignador «personalizado»; de otro modo, los programadores evitarían usar new y delete es estos casos y desperdiciarían un recurso muy valioso de C++. A la hora de sobrecargar operator new() y operator delete() es importante tener en cuenta que lo único que se está cambiando es la forma en que se realiza la asignación del espacio. El compilador llamará a la nueva versión de new en lugar de al original, para asignar espacio, llamando después al constructor que actuará sobre él. Así que, aunque el compilador convierte una expresión new en código para asignar el espacio y para llamar al constructor, todo lo que se puede cambiar al sobrecargar new es la parte correspondiente a la asignación. delete tiene una limitación similar. Cuando se sobrecarga operator new(), se está reemplazando también el modo de tratar los posibles fallos en la asignación de la memoria. Se debe decidir qué acciones va a realizar en tal caso: devolver cero, un bucle de reintento con llamada al new-handler, o lo que es más frecuente, disparar una excepción bad_alloc (tema que se trata en el Volumen 2). La sobrecarga de new y delete es como la de cualquier otro operador. Existe la posibilidad de elegir entre sobrecarga global y sobrecarga para una clase determinada. Sobrecarga global de new y delete Este es el modo más drástico de abordar el asunto, resulta útil cuando el comportamiento de new y delete no es satisfactorio para la mayor parte del sistema. Al sobrecargar la versión global, quedan inaccesibles las originales, y ya no es posible llamarlas desde dentro de las funciones sobrecargadas. El new sobrecargado debe tomar un argumento del tipo size_t (el estándar de C) para tamaños. Este argumento es generado y pasado por el compilador, y se refiere al tamaño del objeto para el que ahora tenemos la responsabilidad de la asignación de memoria. Debe devolver un puntero a un bloque de ese tamaño, (o mayor, si hubiera motivos para hacerlo así), o cero en el caso de no se encontrara un bloque adecuado. Si eso sucede, no se producirá la llamada al constructor. Por supuesto, hay que hacer algo más informativo que sólo devolver cero, por ejemplo llamar al «new-handler» o disparar una excepción, para indicar que hubo un problema. El valor de retorno de operator new() es void*, no un puntero a un tipo particular. Lo que hace es obtener un bloque de memoria, no un objeto definido, no hasta 391 ✐ ✐ ✐ ✐

✐<br />

✐<br />

✐<br />

“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 390 — #428<br />

✐<br />

Capítulo 13. Creación dinámica de objetos<br />

La forma de reemplazar el manejador de new-handler por defecto consiste <strong>en</strong> incluir<br />

el archivo new.h y hacer una llamada a la función set_new_handler() con<br />

la dirección de la función que se desea instalar:<br />

//: C13:NewHandler.cpp<br />

// Changing the new-handler<br />

#include <br />

#include <br />

#include <br />

using namespace std;<br />

int count = 0;<br />

void out_of_memory() {<br />

cerr

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!