Kann unter irgendwelchen Umständen etwas in die Klammern bei new[] geschrieben werden?



  • Also ich meine wenn man sagt new int[20](); ob die Klammern überhaupt irgendwas annehmen, oder ob die nur leer akzeptiert werden.



  • operator new[] ruft imho immer den Default-Konstruktor auf. Es ist also nicht möglich Parameter zu übergeben (wenn man von Default-Parametern absieht).

    Gruß
    Don06



  • Don06 schrieb:

    operator new[] ruft imho immer den Default-Konstruktor auf. Es ist also nicht möglich Parameter zu übergeben (wenn man von Default-Parametern absieht).

    Gruß
    Don06

    Falsch.



  • /edit: Blödsinn meinerseits...



  • int* bla = new int[3](3);
    
    error C2075: 'Target of operator new()' : array initialization needs curly braces
    

    Das selbe mit Objekttypen.



  • () schrieb:

    int* bla = new int[3](3);
    
    error C2075: 'Target of operator new()' : array initialization needs curly braces
    

    Das selbe mit Objekttypen.

    afaik geht das so:

    int* bla = new int[3]{3, 3, 3};
    


  • int* bla = new int[3]{3, 3, 3};

    error C2143: syntax error : missing ';' before '{'
    

    Aber das war ja auch gar nicht die Frage, sondern ob die Klammern überhaupt unter irgendwelchen Umständen nicht leer sein können



  • mein obiger Beitrag war natürlich völliger Humbug. Die Konstruktor-Argumente für die einzelnen Array-Elemente sind natürlich in geschweiften Klammern zu übergeben.
    Aber: es ist möglich, operator new mit mehr Argumenten als dem obligatorischen size_t zu überladen, z.B. gibts standardmäßig die überladungen mit void* oder std::nothrow_t als zweitem Parameter (inplace-new und nothrow-new). Entsprechend kann auch operator new[] mit zusätzlichen parametern aufgerufen werden, bsp:

    int* array = new int[29](std::nothrow); //nothrow-new
    class C;
    void* ptr = ::operator new[](10*sizeof(C)); // nur Speicher holen
    C* cptr = new C[10](ptr); //placement-new
    
    class D {
      /*...*/
      operaotr new[](size_t size, int i, char c); //eigene Erfindung
    };
    D* dptr = new D[12](5, 'f'); //Aufruf der eigenen Erfindung
    

    bei der dritten Zeile bin ich mir nicht ganz sicher, ob das so korrekt ist, aber irgenwie in der Art kann man sich "rohen" Speicher besorgen.
    Tatsache ist: man muss zwischen der Funktion operator new und dem Operator new unterscheiden:

    • operator new kann man überladen und wird hier in Zeile 3 explizit aufgerufen wird, sonst (normalerweise) nur indirekt durch den Operator new
      - der Operator new ist nicht überladbar. Er ruft den jeweiligen operator new auf und konstruiert danach die Objekte im entsprechenden Speicherbereich.


  • Kannst du zum dritten ein vollständiges Beispiel posten?
    Weil bei mir machters net.


  • Mod

    Der new-Operator nimmt zusätzliche Argumente auf zweierlei Weise an:
    1. unmittelbar nach dem Schlüsselwort new: diese sog. placement-Form erlaubt es, zusätzliche Argumente an die Allokationsfunktion (also die operator new-Funktion) zu übergeben. Die Bezeichnung placement-new leitet sich von der Standardvariante ab, bei der zusätzlich ein Zeiger auf bereits reservierten Speicher übergeben wird, um das neue Objekt dort zu erstellen. nothrow new führt streng genommen keine platzierte Objekterstellung durch, trotzdem fällt dies unter den gleichen Begriff. Während der delete-Operator keine placement-Form hat, werden entsprechende operator delete-placement-Funktionen dennoch dann aufgerufen, wenn bei einem placement-new-Aufruf bei der Erzeugung des Objektes eine Exception auftritt (das kann also nur bei Klassen oder Arrays aus solchen Klassen passieren, die über einen nicht-trivialen Konstruktor verfügen).

    2. nach der typeid oder new-typeid. Falls der bezeichnete Typ kein Array ist, können in Klammern ein initialisierender Ausdruck bzw. Konstruktorargumente angegeben werden. Ein leeres Klammerpaar führt dagegen zu value-Initialisierung des Objektes. Werden keine Klammern angegeben, so wird das Objekt nur Initialisiert, wenn es sich nicht um ein POD handelt, dann wird das Objekt ebenfalls value-Initialisiert. Falls der Typ ein Array ist, so ist nur ein leeres Klammerpaar oder dessen Auslassung (bei ansonsten gleicher Semantik) zulässig - es ist also nicht möglich, bestimmte Argumente für die einzelnen Elemente des Arrays anzugeben.
    Es ist ebenfalls nicht möglich, diese Argumente auf dem Umweg eines placement-news doch noch (direkt) eine andere Initialisierung durchzuführen. Falls es sich nicht um ein Array aus PODs handelt, ist das sowieso klar: was immer die placement-new-Funktion mit dem Speicher anstellt, die darauffolgende Initialisierung wird das immer zunichte machen. Aber auch bei PODs ist es nicht anders: in diesem Falle ist der Inhalt nach dem new-Operator unbestimmt (5.3.4/15) un muss nicht vom Inhalte des Speichers unmittelbar nach der Rückkehr aus der Allokationsfunktion abhängen. Wäre das anders, könnte man das Standard-placement-new als elegante (und ausnahmsweise mal legale) Variante des "union-casts" betrachten.

    @pumuckl:

    int* array = new int[29](std::nothrow); //nothrow-new
    class C;
    void* ptr = ::operator new[](10*sizeof(C)); // nur Speicher holen
    C* cptr = new C[10](ptr); //placement-new
    

    es muss heißen:

    int* array = new(std::nothrow) int[29];
    C* cptr = new(ptr) C[10];
    

    (C muss selbstverständlich an dieser Stelle auch noch vollständig definiert sein)

    class D {
      /*...*/
      operator new[](size_t size, int i, char c); //eigene Erfindung
    };
    D* dptr = new D[12](5, 'f'); //Aufruf der eigenen Erfindung
    

    dito:

    D* dptr = new(5,'f') D[12];
    

    Aber dies kann, wie schon beschrieben, nicht dazu benutzt werden, um die Ds doch noch auf andere Weise zu initialisieren.

    Bleibt noch zu erwähnen, dass sich in C++0x bei der Initialisierungssyntax einiges ändern wird, wenn ich mich richtig erinnere, betrifft dies auch den new-Operator.



  • Sry war da wiedermal nicht ganz Syntax-sicher.


Anmelden zum Antworten