programacion - que es include en c++
¿Cuándo se necesita la biblioteca#include<new> en C++? (4)
El operador new
definido en el encabezado <new>
arroja la excepción bad_alloc
(que se declara en el mismo encabezado) en lugar de devolver NULL cuando la asignación de memoria no es posible. <new>
encabezado <new>
también define
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
variante que no arroja excepciones y colocación nueva variante. Sin . Las tres sobrecargas del operador: <new>
obtienes solo el antiguo operator new
devolución NULL operator new
void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
void* operator new (std::size_t size, void* ptr) throw();
se declaran en el encabezado <new>
. Sin embargo, algunos compiladores pueden ponerlos a disposición implícitamente, pero esto no es estándar, y no debe confiar en él.
De acuerdo con esta entrada de referencia para operador nuevo ( http://www.cplusplus.com/reference/std/new/operator%20new/ ):
Las funciones del operador de almacenamiento dinámico global son especiales en la biblioteca estándar:
- Las tres versiones de operador nuevo se declaran en el espacio de nombres global, no en el espacio de nombres estándar.
- La primera y la segunda versión se declaran implícitamente en cada unidad de traducción de un programa C ++: no es necesario incluir el encabezado para que estén presentes.
Me parece que esto implica que la tercera versión del operador nuevo (colocación nueva) no se declara implícitamente en cada unidad de traducción de un programa C ++ y el encabezado <new>
sí necesita incluirse para que esté presente. ¿Es eso correcto?
Si es así, ¿cómo es que usando los compiladores g ++ y MS VC ++ Express parece que puedo compilar código usando la tercera versión de nuevo sin #include <new>
en mi código fuente?
Además, la entrada de referencia MSDN Standard C ++ Library en operator new da algún código de ejemplo para las tres formas de operador new que contiene la instrucción #include <new>
; sin embargo, el ejemplo parece compilar y ejecutar lo mismo para mí sin incluir esto
// new_op_new.cpp
// compile with: /EHsc
#include<new>
#include<iostream>
using namespace std;
class MyClass
{
public:
MyClass( )
{
cout << "Construction MyClass." << this << endl;
};
~MyClass( )
{
imember = 0; cout << "Destructing MyClass." << this << endl;
};
int imember;
};
int main( )
{
// The first form of new delete
MyClass* fPtr = new MyClass;
delete fPtr;
// The second form of new delete
char x[sizeof( MyClass )];
MyClass* fPtr2 = new( &x[0] ) MyClass;
fPtr2 -> ~MyClass();
cout << "The address of x[0] is : " << ( void* )&x[0] << endl;
// The third form of new delete
MyClass* fPtr3 = new( nothrow ) MyClass;
delete fPtr3;
}
¿Podría alguien arrojar algo de luz sobre esto y cuándo y por qué es posible que necesite #include <new>
- tal vez algún código de ejemplo que no se compile sin #include <new>
?
Gracias.
El versículo 3.7.4.2 del Estándar de C ++ dice: -
La biblioteca proporciona definiciones predeterminadas para las funciones globales de asignación y desasignación. Algunas funciones globales de asignación y desasignación son reemplazables (18.6.1). Un programa C ++ debe proporcionar como máximo una definición de una función reemplazable de atribución o desasignación. Cualquier definición de función reemplaza la versión predeterminada proporcionada en la biblioteca (17.6.3.6). Las siguientes funciones de asignación y desasignación (18.6) se declaran implícitamente en alcance global en cada unidad de traducción de un programa.
void* operator new(std::size_t) throw(std::bad_alloc);
void* operator new[](std::size_t) throw std::bad_alloc);
void operator delete(void*) throw();
void operator delete[](void*) throw();
Estas declaraciones implícitas introducen solo el operador de nombres de función new, operator new [], operator delete, operator delete []. [Nota: las declaraciones implícitas no introducen los nombres std, std :: bad_alloc, y std :: size_t, o cualquier otro nombre que la biblioteca use para declarar estos nombres. Por lo tanto, una llamada de newexpression, delete-expression o function que se refiere a una de estas funciones sin incluir el encabezado está bien formada. Sin embargo, refiriéndose a std, std :: bad_alloc, y std :: size_t está mal formado a menos que el nombre haya sido declarado incluyendo el encabezado apropiado. -Finalizar nota]
Además, la versión std::nothrow
del operator new
requiere la inclusión del encabezado. Sin embargo, el estándar no especifica la inclusión implícita de los archivos de encabezado dentro de otros archivos de encabezado. Por lo tanto, es seguro y portátil seguir el estándar cuando se mencionan los nombres std::bad_alloc
etc.
En cuanto a la pregunta en el título,
"¿ Cuándo se necesita la biblioteca
#include <new>
en C ++?
La palabra clave new
se puede usar de varias maneras. El uso ordinario no requiere la inclusión de ningún encabezado. Pero una forma posible de utilizar esta palabra clave es invocar la función particular de "ubicación nueva" definida por el <new>
encabezado. Con ese uso necesita incluir directa o indirectamente el <new>
encabezado. No incluya ese encabezado ni ningún otro encabezado, a menos que lo necesite; no incluir encabezados por defecto. Por otro lado, no confíe en una versión específica de la implementación de un encabezado que incluya otro: siempre incluya lo que necesita de acuerdo con las especificaciones del estándar (u otras) de lo que proporcionan.
En cuanto a la pregunta en el cuerpo,
" El ejemplo parece compilar y ejecutar lo mismo para mí sin incluir esto?
En C ++, los encabezados de biblioteca estándar pueden incluir otros encabezados de biblioteca estándar (o los elementos proporcionados por otros encabezados de biblioteca estándar), a discreción de la implementación.
Nada en C ++ impide que los encabezados estándar incluyan otros encabezados estándar. Entonces, si incluye un encabezado estándar, es posible que indirectamente los incluya a todos . Sin embargo, este comportamiento depende totalmente de la implementación, y si necesita las características de un encabezado específico, siempre debe incluirlo explícitamente.