2016-07-19 142 views
5

Ci sono molti riferimenti sul processo di compilazione/collegamento, ma mi interessa un problema più concreto: la compilazione di una classe.Come funziona la compilazione di una classe?

La domanda sorge perché in generale è necessario conoscere le cose prima di poterle utilizzare. Ad esempio: non è possibile chiamare la funzione se non è stata dichiarata in precedenza.

Nelle classi, non viene eseguito allo stesso modo. Puoi usare un membro prima che appaia. Cosa fa il compilatore? Lo standard dice qualcosa su una fase precedente della compilazione?

Per essere più specifici, il seguente esempio mostra come utilizzare i membri definiti di seguito.

#include <iostream> 

class EvenOdd { 
public: 
    EvenOdd(): value(0) {} 

    void assignEven(unsigned v) { 
     if (v>0 && v%2==1) { 
     std::cout << "Wrong call... is odd" << std::endl; 
     assignOdd(v); 
     } 
     else { 
     std::cout << "Right..." << v << " is Even" << std::endl; 
     value= v; 
     } 
    } 
    void assignOdd(unsigned v) { 
     if (v>0 && v%2==0) { 
     std::cout << "Wrong call... is even" << std::endl; 
     assignEven(v); 
     } 
     else { 
     std::cout << "Right..." << v << " is Odd" << std::endl; 
     value= v; 
     } 
    } 
private: 
    unsigned value; 
}; 

int main() 
{ 
    EvenOdd a; 
    std::cout << "Do it right..." << std::endl; 
    a.assignEven(2); 
    std::cout << "doing it wrong..." << std::endl; 
    a.assignEven(3); 
} 

Potremmo anche aggiungere ulteriori domande su funzioni inline, come può essere definito dopo il punto di chiamata e il compilatore può risolvere senza problemi. Immagino che la risposta sia correlata.

AGGIORNAMENTO: So che la compilazione/collegamento ha diversi passaggi. D'altra parte, se il compilatore accetta di chiamare una funzione definita sotto, è dovuto al fatto che il compilatore ha analizzato il codice in un certo senso. La domanda è ¿quale tipo di stage precedente è fatto prima? Inoltre ... in quale parte dello standard troviamo qualcosa relativo all'utilizzo di un membro definito di seguito?

Sapere come funziona il compilatore è molto interessante perché deve conoscere i dettagli della funzione qui sotto (almeno l'intestazione) che sembra corrispondere effettivamente alla compilazione. Anche il membro dei dati deve essere compilato perché devi correlare il suo tipo nel contesto della funzione sopra

Funziona come se il codice sia stato riordinato ma non è coerente con l'esempio precedente perché entrambi i membri della funzione si chiamano. È come riordinare i membri dei dati e l'intestazione delle funzioni potrebbe essere il codice che viene considerato dal compilatore.

+0

La compilazione ha più di un passaggio. – axiac

+1

@axiac Sì, ma OP sembra saperlo. Immagino che chiedano davvero perché è necessario avere una dichiarazione preliminare per una funzione, ma non per un membro della classe. Sembra incoerente. – luk32

+0

Grazie @ luk32, questa è la domanda! – EFenix

risposta

7

Lo standard dice

Una classe è considerato un tipo completamente definito oggetto (3,9) (o tipo completo) alla chiusura } della classe-specificatore. All'interno della specifica dei membri della classe, la classe è considerata completa all'interno dei corpi delle funzioni, degli argomenti predefiniti, delle specifiche delle eccezioni e degli inizializzatori dei membri predefiniti (comprese le cose nelle classi annidate). Altrimenti è considerato incompleto all'interno della sua specifica di membro della classe.

Ciò significa in particolare che un organismo di funzioni membro può fare riferimento ai membri della classe dichiarati sotto di esso. Lo standard non si cura di come le implementazioni raggiungono questo obiettivo. Un possibile metodo potrebbe essere quello di posticipare l'analisi semantica dei corpi delle funzioni dei membri e degli altri elementi specificati sopra fino a quando viene visualizzata la parentesi di chiusura della classe.

0

Le funzioni all'interno delle classi possono accedere e modificare (a meno che la funzione sia costante) membri dati senza dichiararli, poiché i membri dati sono già dichiarati nella classe. Nella tua risposta al perché la funzione non ha bisogno di una dichiarazione in classe.

+0

purtroppo 5 minuti in ritardo ... (y) – hsqureshi