2017-07-07 1 views
1

Ich kann einige Probleme nicht verstehen, wenn ich neu lerne/Überladung lösche. Fragen:Überladungsoperator new(), warum Konstruktor zweimal aufgerufen wird?

  1. Warum neue vor dem Konstruktor, Destruktor vor dem Löschen aufgerufen wird?
  2. Warum wird Konstruktor zweimal aufgerufen, wenn :: new?

ich den Code hier angefügt haben:


#include<iostream> 

using namespace std; 

class MyClass 
{ 
public: 
    MyClass() { 
     cout << "My Class is Constructed !" << endl; 

    } 

    ~MyClass() { cout << "My Class is Deleted ! " << endl; } 

    static void *operator new(size_t Size) 
    { 
     cout << "new call" << endl; 
     MyClass *p = ::new MyClass; 
     return p; 
    } 
    static void operator delete(void *p) 
    { 
     cout << "delete call" << endl; 
     ::delete p; 
    } 

}; 
int main() 
{ 
    MyClass *p = new MyClass; 
    delete p; 
    cin.get(); 
    return 0; 
} 

output: 
new call 
My Class is Constructed ! 
My Class is Constructed ! 
My Class is Deleted ! 
delete call 

+7

Sie sollten nicht ':: new MyClass' innerhalb' MyClass :: operator new' machen. Der Zweck dieser Funktion ist die Zuweisung von Speicher ohne Aufruf von Konstruktoren, aber Sie machen einen Konstruktoraufruf (deshalb sehen Sie 2 Konstruktoraufrufe - entsprechend Ihren beiden Verwendungen des 'neuen' Ausdrucks). –

+0

Für Ihre Frage 1 muss natürlich Speicherplatz eingeholt werden, bevor ein Objekt darin konstruiert werden kann; und das Objekt muss zerstört werden, bevor der Speicher freigegeben wird –

+1

@ M.M: Antwort Abschnitt ist unten. –

Antwort

3

Der Grund, warum dies geschieht, weil, wenn Sie etwas mit new zuweisen, die Zuweisung und der Bau geschieht in zwei Phasen. Die erste ist die tatsächliche Zuweisung und die zweite ist die Konstruktion über die Platzierung neu.

Die von Ihnen zur Verfügung gestellte Überlast dient nur zur Speicherzuweisung (daher der Parameter size_t), stattdessen haben Sie new für die Klasse aufgerufen, die beide Schritte von oben ausführt. Sie sollten den Speicher nur in dieser Funktion zuordnen. Ändern Sie also Ihre Funktion zu

static void *operator new(size_t size) 
{ 
    return ::operator new(size); 
} 

Und Sie werden sehen, die Klasse wird nur einmal gebaut.

+0

so, löschen etwas hat auch zwei Phasen, Zerstörung und den Speicher frei? Warum wird Destruktor nur einmal aufgerufen? – JackChen

+1

@JackChen Da Sie es nur einmal aufgerufen haben, wird der Konstruktor zweimal aufgerufen, weil Sie ihn zweimal aufgerufen haben. – EJP

+0

@JackChen EJP hat recht, wenn Sie in Ihrer Überladung für 'operator delete' bemerken, dass Sie' :: delete' auf einem void-Zeiger aufgerufen haben, der gerade Speicher freigibt, Sie haben nicht versucht, den void-Zeiger auf 'static_cast' zu setzen Zeiger auf 'MyClass' und dann der Destruktor genannt, deshalb erhalten Sie nur einen Destruktoraufruf – Curious

Verwandte Themen