C++11 introduit nullptr
, il est connu comme l' Null
pointeur constant et améliore la sécurité de type et résout des situations ambiguës à la différence de l'existant mise en œuvre dépend de pointeur null constante NULL
. Pour être en mesure de comprendre les avantages de l' nullptr
. nous avons d'abord besoin de comprendre qu'est - NULL
, et quels sont les problèmes associés.
Qu'est - NULL
exactement?
Avant C++11 NULL
a été utilisé pour représenter un pointeur qui n'a pas de valeur ou un pointeur qui ne pointe sur rien de valable. Contrairement à l'idée populaire NULL
n'est pas un mot-clé en C++. C'est un identificateur défini dans la norme en-têtes de bibliothèque. En bref vous ne pouvez pas utiliser NULL
sans, y compris certains de la bibliothèque standard les en-têtes. Considérons l' Exemple de programme:
int main()
{
int *ptr = NULL;
return 0;
}
Sortie:
prog.cpp: In function 'int main()':
prog.cpp:3:16: error: 'NULL' was not declared in this scope
Le standard C++ définit la valeur NULL comme une mise en œuvre définies macro définie dans la norme de la bibliothèque de fichiers d'en-tête.
L'origine de la valeur NULL est à partir de C et de C++ hérité de C. C standard défini comme NULL ou 0 (void *)0. Mais en C++ il y a une différence subtile.
C++ ne pouvait pas accepter cette spécification comme il est. Contrairement au C, C++ est un langage fortement typé.(C ne nécessite pas de cast explicite, tandis que d' void*
de tout type, tandis que le C++ mandats un cast explicite) .Cela rend la définition de la valeur NULL spécifié par la norme C inutile dans de nombreux C++ expressions, par exemple:
std::string * str = NULL; //Case 1
void (A::*ptrFunc) () = &A::doSomething;
if (ptrFunc == NULL) {} //Case 2
Si la valeur NULL est définie comme (void *)0. Les deux expressions ci-dessus ne fonctionnerait pas.
-
Cas 1: ne compile pas car une automatique cast est nécessaire d'
void *
de std::string
.
-
Cas 2: ne compile pas parce que les acteurs de
void *
de pointeur de fonction membre est nécessaire.
Donc, contrairement au C, C++ Standard pour mandat de définir la valeur NULL comme littéral numérique 0 ou 0L.
Alors, quel est le besoin pour un autre pointeur null constante lorsque nous avons NULL
déjà?
Si C++ comité de normalisation est venu avec une valeur NULL définition qui va travailler pour C++, cette définition a son propre lot de problèmes. NULL suffisamment bien fonctionné pour presque tous les scénarios, mais pas tous. Il a donné surprenant et des résultats erronés pour certains rares scénarios. Par exemple:
#include<iostream>
void doSomething(int)
{
std::cout<<"In Int version";
}
void doSomething(char *)
{
std::cout<<"In char* version";
}
int main()
{
doSomething(NULL);
return 0;
}
Sortie:
In Int version
Clairement, l'intention semble être d'appeler la version qui prend en char* comme argument, mais comme le résultat montre la fonction qui prend un int version est appelée. C'est parce que la valeur NULL est un littéral numérique.
En outre, Depuis qu'elle est définie par l'implémentation de savoir si la valeur NULL peut être 0 ou 0L il peut y beaucoup de confusion dans la fonction de résolution de surcharge.
Exemple De Programme:
#include <cstddef>
void doSomething(int);
void doSomething(char *);
int main()
{
doSomething(static_cast <char *>(0)); // Case 1
doSomething(0); // Case 2
doSomething(NULL) // Case 3
}
L'analyse de l'extrait ci-dessus:
-
Cas 1: appels
doSomething(char *)
comme prévu
-
Cas 2: appels d'
doSomething(int)
mais peut-être qu' char*
version a été à désirer, car 0
EST aussi un pointeur null.
-
Cas 3: Si
NULL
est défini comme 0
,
appels doSomething(int)
quand doSomething(char *)
a été destiné, peut-être qui en résulte dans la logique d'erreur lors de l'exécution.
Tandis que, si NULL
est défini comme 0L
,
L'appel est ambigu et les résultats dans d'erreur de compilation.
Donc, en fonction de la mise en œuvre du même code peut donner des résultats divers, ce qui est clairement indésirable. Naturellement, le C++ comité des normes a voulu corriger cela et c'est la première motivation pour nullptr.
Donc, qu'est - nullptr
et comment il évite les problèmes d' NULL
?
C++11 introduit un nouveau mot clé nullptr pour servir de pointeur null constante. Contrairement à NULL, son comportement n'est pas définie par l'implémentation. Ce n'est pas une Macro, mais il a son propre type. nullptr a le type std::nullptr_t
. C++11 de façon appropriée définit les propriétés de l'nullptr pour éviter les inconvénients de NULL. Pour résumer ses propriétés:
Propriété 1: Il possède son propre type std::nullptr_t
et
Propriété 2: Il est implicitement convertible et comparable à n'importe quel type de pointeur ou un pointeur de type de membre, mais
Propriété 3: Il n'est pas implicitement convertible ou comparable à celle des types intégraux, sauf pour bool
.
Considérons l'exemple suivant:
#include<iostream>
void doSomething(int)
{
std::cout<<"In Int version";
}
void doSomething(char *)
{
std::cout<<"In char* version";
}
int main()
{
char *pc = nullptr; // Case 1
int i = nullptr; // Case 2
bool flag = nullptr; // Case 3
doSomething(nullptr); // Case 4
return 0;
}
Dans le programme ci-dessus,
-
Cas 1: OK - Propriété 2
-
Cas 2: Pas Ok - Propriété 3
-
Cas 3: OK - Propriété 3
-
Cas 4: Pas de confusion des Appels -
char *
version, Propriété 2 & 3
Ainsi, l'introduction de nullptr évite tous les problèmes de la bonne vieille NULL.
Où et comment devriez-vous utiliser nullptr
?
La règle de base de C++11 est tout simplement commencer à utiliser nullptr
chaque fois que vous avez utilisée d'une autre manière NULL dans le passé.
Référence:
C++11 Standard: C. 3.2.4 Macro NULL
C++11 Standard: 18.2 Types
C++11 Standard: 4.10 Pointeur de conversions
Standard C99: 6.3.2.3 Pointeurs