2016-05-01 16 views
1

Ist es möglich, dass C++ beim Aufrufen einer Methode auf ein nullptr-Objekt eine NPE auslöst, anstatt in ein undefiniertes Verhalten zu gehen? Ich könnte einen Handler für ein SEGFAULT-Signal erstellen, aber das wäre wirklich gefährlich, weil nicht jedes SEGFAULT eine NullPointerException ist. Wenn ich es durch einfaches Einchecken einer if-Klausel tun muss, gibt es einen effizienten Weg dazu? Vielleicht auch auf Compiletime?Eine NullPointerException in C++ werfen

+1

sicherlich möglich, die Frage ist, ist es sinnvoll? Versuchst du etwas zu debuggen? Kann Ihr Programm auf irgendeine Weise nützlich sein, selbst wenn es einen Nullzeiger dereferenzieren muss? – Jfevold

+0

Ich versuche, eine kleine Programmiersprache zu programmieren, und da ich nach C++ kompiliere, aber kein undefiniertes Verhalten habe, würde ich gerne wissen, wie ich damit umgehen könnte – Exagon

+0

Es gibt kein "nullptr object". Entweder hast du ein Objekt oder du hast kein Objekt. Wenn Sie dies nicht tun, können Sie Elementfunktionen für ein Objekt nicht aufrufen, da Sie kein Objekt haben, für das eine Elementfunktion aufgerufen werden soll. –

Antwort

2

Ja können Sie, aber es ist nicht wirklich eine gute Idee (Sie sollten Zeiger sowieso nicht behandeln, in modernen C++ - Zeigern sind in Objekten gehalten, die ihre Lebensdauer verwalten).

Sie können immer eine Klasse definieren, die den Zeiger enthält. Dann, wenn Sie versuchen und operator->() verwenden, wird es werfen, wenn der gehaltene Zeiger nullptr ist.

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 führt die Klasse std :: optional ein, die die gleiche Funktionalität bietet (über die Ausnahme std :: bad_optional_access). – daddesio

0

Eine andere Möglichkeit, die Ausnahmebehandlung: eine Funktion mit NULL-Zeiger

#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; 
} 

Ausgabe Aufruf:

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