none - nullptr c++
C++ NULL vs__null (3)
Tengo el siguiente código:
MyType x = NULL;
NetBeans me dio una sugerencia para cambiarlo a esto:
MyType x = __null;
Lo busqué y descubrí que __null
se llama "palabra clave del compilador", que asumí que significa que se usa internamente para el compilador. No entiendo por qué NetBeans sugirió cambiarlo a una palabra clave del compilador.
¿Cuál es la diferencia entre NULL
y __null
en c ++?
NULL
es el antiguo símbolo C para un puntero nulo. C ++ tradicionalmente ha usado 0
para los punteros nulos, y desde el estándar de C ++ 11 nullptr
.
Teniendo en cuenta que x
no parece ser un puntero, entonces no puede inicializar x
para ser un puntero nulo, y el símbolo __null
es quizás un símbolo interno del compilador para un valor nulo (que es un concepto que realmente no existe). en el estándar C ++).
Si desea que x
inicialice en algún estado predeterminado, debe confiar en el constructor predeterminado MyClass
para inicializar los objetos y sus variables miembro a algunos valores predeterminados adecuados.
NULL
ha sido superado de C a C ++ y, antes de C ++ 11, adoptó su significado de C:
hasta C ++ 11: La macro NULL es una constante de puntero nulo definida por la implementación, que puede ser una constante constante rvalue de tipo entero que se evalúa a cero.
C ++ 11 luego introdujo un puntero nulo dedicado literal nullptr
de tipo std::nullptr_t
. Pero, probablemente por compatibilidad con versiones anteriores, la macro NULL
no se eliminó; su definición fue un poco relajada, ya que los compiladores ahora pueden definirla como integral o como tipo de puntero:
C ++ 11 en adelante: un literal entero con valor cero, o un prvalue de tipo std :: nullptr_t
Si usa NULL
, entonces obtiene un comportamiento definido por la implementación en la resolución de sobrecarga. Considere, por ejemplo, el siguiente código con un compilador que usa la versión integral de NULL
-macro. Luego, una llamada que usa NULL
como parámetro pasado a una función puede llevar a ambigüedades:
struct SomeOverload {
SomeOverload(int x) {
cout << "taking int param: " << x << endl;
}
SomeOverload(void* x) {
cout << "taking void* param: " << x << endl;
}
};
int main() {
int someVal = 10;
SomeOverload a(0);
SomeOverload b(&someVal);
// SomeOverload c(NULL); // Call to constructor is ambiuous
SomeOverload d(nullptr);
}
Por lo tanto, se recomienda utilizar nullptr
siempre que desee expresar el tipo de puntero.
Y no use __null
, ya que es una constante no portátil específica del compilador; nullptr
, por el contrario, es perfectamente portátil.
__null
es una cosa interna de g++
que sirve aproximadamente para el mismo propósito que la nullptr
estándar agregada en C ++ 11 (que actúa de manera consistente como un puntero, nunca como un entero).
NULL
se define como 0
, que puede usarse implícitamente como entero, booleano, valor de punto flotante o puntero, lo cual es un problema cuando se trata de resolución de sobrecarga, cuando se desea llamar a la función que toma un puntero específicamente.
En cualquier caso, no debe usar __null
porque es un detalle de implementación de g++
, por lo que usarlo garantiza un código no portátil. Si puede confiar en C ++ 11 (seguramente ya puede nullptr
), use nullptr
. Si no, NULL
es tu única opción portátil.