2016-05-01 1 views
1

Est-il possible de laisser C++ lancer un NPE lors de l'appel d'une méthode sur un objet nullptr, au lieu d'aller dans un comportement indéfini? Je pourrais créer un gestionnaire pour un signal SEGFAULT mais cela serait vraiment dangereux, parce que chaque SEGFAULT n'est pas une exception NullPointerException. Si je dois le faire en cochant simplement une clause if, y a-t-il un moyen efficace de le faire? Peut-être aussi sur compiletime?Lançant une exception NullPointerException en C++

+1

certainement possible, la question est, est-il utile? Essayez-vous de déboguer quelque chose? Est-ce que votre programme peut toujours être utile d'une certaine façon même s'il doit déréférencer un pointeur nul? – Jfevold

+0

J'essaye de coder un petit langage de programmation et comme je compile en C++, mais je ne veux pas avoir de comportement indéfini, je voudrais savoir comment je pourrais gérer cela – Exagon

+0

Il n'y a pas d'objet "nullptr". Soit vous avez un objet, soit vous ne l'avez pas. Si vous ne le faites pas, vous ne pouvez pas appeler les fonctions membres sur un objet, car vous n'avez pas d'objet sur lequel appeler une fonction membre. –

Répondre

2

Oui, vous pouvez mais ce n'est pas vraiment une bonne idée (vous ne devriez pas gérer les pointeurs de toute façon, dans les pointeurs modernes C++ sont détenus à l'intérieur des objets qui gèrent leur durée de vie).

Vous pouvez toujours définir une classe qui contient le pointeur. Ensuite, lorsque vous essayez d'utiliser operator->() il lancera si le pointeur maintenu est nullptr.

template<typename T> 
class ThrowingUniquePtr 
{ 
    T* ptr; 
    public: 
     // STUFF to create and hold pointer. 

     T* operator->() 
     { 
      if (ptr) { 
       return ptr; 
      } 
      throw NullPointerException; // You have defined this somewhere else. 
     } 
}; 

class Run 
{ 
    public: 
     void run() {std::cout << "Running\n";} 
}; 
int main() 
{ 
    ThrowingUniquePtr<Run> x(new Run); 
    x->run(); // will call run. 

    ThrowingUniquePtr<Run> y(nullptr); 
    y->run(); // will throw. 
} 
+0

C++ 17 introduit la classe std :: optionnelle qui fournit la même fonctionnalité (via l'exception std :: bad_optional_access). – daddesio

0

Une autre façon de la gestion des exceptions: appeler une fonction en utilisant le pointeur NULL

#include <iostream> 
#include <typeinfo> 
using namespace std; 

char str_NullPointer[25] = "NULL Pointer exception"; 
char str_Arithmetic[25] = "Arithmetic exception"; 

class A 
{ 
public: 
    int i = 20; 
public: 
    int function() 
    { 
     printf("Function start\n"); 

     try 
     { 
      if (this) 
      { 
       printf("value of i = %d \n", i); 
      } 
      else 
      { 
       throw str_NullPointer;   /* Exception thrown in Case 2 */ 
      } 
     } 
     catch(const int s) 
     { 
      printf("%d\n", s); 
     } 
     catch(const char* s) 
     { 
      printf("%s in %s\n", s, typeid(this).name()); /* Exception and Class Name */ 
     } 

     printf("Function end\n\n\n"); 
    } 
}; 

int main() { 
    //code 

printf("Case 1: With Pointer\n"); 
A *obj = new A(); 
obj->i = 20; 
obj->function(); 

printf("Case 2: With NULL Pointer\n"); 
delete obj; 
obj = NULL; 
obj->function(); 

return 0; 
} 

Sortie:

Case 1: With Pointer 
Function start 
value of i = 20 
Function end 


Case 2: With NULL Pointer 
Function start 
NULL Pointer exception in P4abcd 
Function end