2013-07-31 15 views
10

Ho notato che il costruttore si sposterà da this a eax prima di tornare. Questo è un valore di ritorno o qualcos'altro?perché i costruttori "restituiscono" questo puntatore?

class CTest { 
    int val_; 
public: 
    CTest() { 
0093F700 push  ebp 
0093F701 mov   ebp,esp 
0093F703 sub   esp,0CCh 
0093F709 push  ebx 
0093F70A push  esi 
0093F70B push  edi 
0093F70C push  ecx 
0093F70D lea   edi,[ebp-0CCh] 
0093F713 mov   ecx,33h 
0093F718 mov   eax,0CCCCCCCCh 
0093F71D rep stos dword ptr es:[edi] 
0093F71F pop   ecx 
0093F720 mov   dword ptr [this],ecx 
     val_ = 1; 
0093F723 mov   eax,dword ptr [this] 
0093F726 mov   dword ptr [eax],1 
    } 
0093F72C mov   eax,dword ptr [this] 
0093F72F pop   edi 
0093F730 pop   esi 
0093F731 pop   ebx 
0093F732 mov   esp,ebp 
0093F734 pop   ebp 
0093F735 ret 

modalità debug VS2012


ho scoperto che new userà il suo "valore di ritorno". Sembra if(operator new() == 0) return 0; else return constructor();

class CTest { 
    int val_; 
public: 
    CTest() { 
     val_ = 1; 
     __asm { 
      mov   eax, 0x12345678 
      pop   edi 
      pop   esi 
      pop   ebx 
      mov   esp,ebp 
      pop   ebp 
      ret 
     } 
    } 
}; 

int main() { 
    CTest *test = new CTest; // test == 0x12345678 
    return 0; 
} 
+2

I costruttori non restituiscono nulla, offrono solo l'opportunità di inizializzare l'oggetto creato. –

+0

È un'ipotesi selvaggia, ma suppongo che sia per supportare la costruzione di sottoclassi. – Mehrdad

+17

È un dettaglio di implementazione. Il costruttore standard Per C++ non restituisce nulla e non dovresti fare affidamento su questo. [alcune discussioni SO correlate] (http://stackoverflow.com/questions/10356109/c-constructors-have-no-return-type-just-exactly-why) – Tony

risposta

1

tua seconda domanda non è d'accordo con il primo. In che modo if (operator new() == 0) return 0; else return constructor();if (operator new() == 0) return 0; else return constructor(); può utilizzare se il risultato della condizione è constructor()?

Comunque ...

  1. Quello che il compilatore fa con registri è il business del compilatore. I registri tendono a contenere qualsiasi informazione sia immediatamente utile, e se il compilatore è scritto con la convinzione che ogni volta che viene utilizzato il costruttore, l'oggetto viene usato subito dopo, può ragionevolmente scegliere di mettere this in un registro.

    Un ABI può richiedere costruttori per fare questo, ma dubito che qualcuno lo faccia. Ad ogni modo, tali protocolli si applicano solo alle cose esportate dalle biblioteche, non strettamente all'interno dei programmi.

  2. Qualsiasi espressione new controlla il risultato di operator new rispetto a 0 prima di procedere all'inizializzazione di un oggetto. operator new potrebbe segnalare un errore restituendo nullptr (o NULL, ecc.).

    Questo può effettivamente essere un problema con il posizionamento di nuove espressioni, poiché rappresenta un sovraccarico di runtime inevitabile poiché il puntatore specificato è già noto per essere non nullo.

0

Questa può essere una caratteristica in base alla progettazione, in C++ e altri linguaggi, che restituisce un riferimento ad una determinata istanza permette un utilizzo più "idiomatica" delle funzionalità offerte dall'oggetto stesso, in breve è il Named parameter Idiom.

Ma questa è solo un'opzione, a volte può essere utile, soprattutto se si è in grado di progettare la libreria in modo che "esegua azioni" senza la necessità di passare una quantità significativa di parametri, quindi la catena di chiamate di metodo rimane leggibile.

+1

Un costruttore non ha mai un valore di ritorno. Una funzione che restituisce un'istanza sarebbe una funzione di fabbrica, non un costruttore. Restituire un * riferimento * a un nuovo oggetto, invece di restituire l'oggetto di per sé, in C++ è un errore a meno che l'oggetto non sia specificamente assegnato in qualche modo. – Potatoswatter

Problemi correlati