new und delete operatoren überladen



  • Schreibst du auch throw int; oder throw std::string; - Meinstens wirft man mit Objekten und nicht mit Typen um sich.



  • Ich kenne mich nicht so genau mit den Details aus, aber hat std::bad_alloc überhaupt einen Default-Ctor? Wenn nicht, müsstest du beim throw-Aufruf noch die richtigen Parameter mitgeben.



  • CStoll schrieb:

    Ich kenne mich nicht so genau mit den Details aus, aber hat std::bad_alloc überhaupt einen Default-Ctor? Wenn nicht, müsstest du beim throw-Aufruf noch die richtigen Parameter mitgeben.

    Also in jeder Doku, die ich gefunden habe, steht einfach nur

    throw(std::bad_alloc);
    

    Ohne Parameter. Und ich mache ja nichts anderes.
    Ich habe z.B. http://de.wikipedia.org/wiki/%C3%9Cberladen herangezogen.

    Gruß,
    M.Incani



  • Außerdem müssen die Operatoren nicht-statische Methoden der Klasse sein. Desweiteren ist sowieso das 'static' bei der Methodenimplementierung zu viel.



  • die statics muessen weg und werfen musst du

    throw std::bad_alloc();
    


  • CStoll schrieb:

    Ich kenne mich nicht so genau mit den Details aus, aber hat std::bad_alloc überhaupt einen Default-Ctor? Wenn nicht, müsstest du beim throw-Aufruf noch die richtigen Parameter mitgeben.

    Danke, es muss:

    std::bad_alloc a;
    throw(a);
    

    heißen. Zumindest kann ich Das compilieren. Auch wenn ich jetzt sagen würde, ich gebe ein lokales Objekt zurück. Aber

    if(NULL == a){
        std::bad_alloc *a new bad_alloc();
        throw(*a);
      }
    

    wird auch nicht compiliert. Das Objekt müßte dann aber der Empfänger der Exception freigeben, und daß empfangene Exceptions deleted werden müßten, wäre mir neu.

    Gruß,
    M.Incani



  • BlackPepper schrieb:

    Danke, es muss:

    std::bad_alloc a;
    throw(a);
    

    heißen. Zumindest kann ich Das compilieren. Auch wenn ich jetzt sagen würde, ich gebe ein lokales Objekt zurück.

    Stimmt. Und das lokale Objekt wird kopiert, wie überall wo man mit blanken Objekten hantiert. Achja: Abkürzen kannst Du das ganze wie rapso, s.o.

    Aber

    if(NULL == a){
        std::bad_alloc *a new bad_alloc();
        throw(*a);
      }
    

    wird auch nicht compiliert. Das Objekt müßte dann aber der Empfänger der Exception freigeben, und daß empfangene Exceptions deleted werden müßten, wäre mir neu.

    Stimmt nicht ganz, da Du widerum ein Objekt zurückgibst. Das wird wie übrlich kopiert, und niemand kann die Exception mehr freigeben. Das von Dir geschilderte Problem würde auftauchen, wenn Du den Zeiger statt des Objekts wirfst (und natürlich auch einen Zeiger fängst).



  • BlackPepper schrieb:

    ...
    Also in jeder Doku, die ich gefunden habe, steht einfach nur

    throw(std::bad_alloc);
    

    ...

    sicher, dass es sich dabei nicht um eine "exception specification" handelt (die syntaktisch etwas komplett Anderes ist) ?

    // exception specification: Sagt aus, dass diese Funktion nur eine bad_alloc() werfen soll.
    // --> in der DEKLARATION der Funktion
    void f() throw(std::bad_alloc)
    {
        .... // irgendwas
        // das Werfen einer exception
        // --> in der DEFINITION der Funktion
        throw std::bad_alloc();
        .... // irgendwas
    }
    

    Gruß,

    Simon2.


  • Mod

    Th schrieb:

    Außerdem müssen die Operatoren nicht-statische Methoden der Klasse sein. Desweiteren ist sowieso das 'static' bei der Methodenimplementierung zu viel.

    Das trifft auf operator new und operator delete gerade nicht zu. Diese Operatoren sind, wenn sie in einer Klasse überladen werden, immer statisch. Es ist nicht notwendig, sie explizit mit static zu deklarien, aber möglich. Es kann ja auch nicht anders sein, da beim Aufruf dieser Operatoren das Objekt noch nicht bzw. nicht mehr existiert.



  • Im Übrigen entsprechen deine operatoren nicht dem üblichen Verhalten

    #include "example.h"
    
    namespace own {
    
    unsigned int Example::refCount = 0;
    
    Example::Example()
    {
    }
    
    Example::~Example()
    {
    }
    
    void* Example::operator new (std::size_t size) throw(std::bad_alloc)
    {
    // Anfragen nach 0 Byte werden als Anfragen auf 1 Byte betrachtet
      if( size == 0 ) {
        size = 1;              
      }
      while( true )
      {
    // Versuche Speicher anzufordern
        void *a = malloc(size);       
    // Wenn erfolgreich, gib ZEiger zurück
        if(NULL != a){           
          return a;                      
        }
    //Schlug dieZuweisung fehl muss der new_handler aufgerufen werden
        new_handler globalHandler = set_new_handler( 0 );
        set_new_handler( globalHandler );
    // Versuch das Problem zu lösen mit dem handler
        if ( globalHandler ) {     
          (*globalHandler)();
        }
    // Wenn nicht, wirf exception
        else {
          throw (std::bad_alloc);    
        }
      }
    
    void Example::operator delete (void *a) throw()        // delete darf nichts werfen
    {
    // Es ist immer sichern, den 0-Zeiger zu löschen
      if( a == 0 ) {
        return;   
      }
      free(a);
    }
    }
    


  • rapso schrieb:

    die statics muessen weg und werfen musst du

    throw std::bad_alloc();
    

    Juhu, jetzt tut alles.

    Danke schön für die guten Tipps!

    Gruß,
    M.Incani


Anmelden zum Antworten