2016-02-04 20 views
6

Voglio capire "questo" puntatore. Ho pensato che "questo" puntatore si riferisse al valore dell'oggetto di classe. Tuttavia, nel seguente codice, ho potuto vedere diversi valori di "questo" puntatore:C++: Capire "questo" puntatore

#include <stdio.h> 

class InterfaceA{ 
public: 
    virtual void funa() = 0; 
}; 

class InterfaceB{ 
public: 
    virtual void funb() = 0; 
}; 

void globala(InterfaceA* obj){ 
    printf("globalA: pointer: %p\n\r",obj); 
} 
void globalb(InterfaceB* obj){ 
    printf("globalB: pointer: %p\n\r",obj); 
} 
class concrete : public InterfaceA, public InterfaceB{ 
public: 
    void funa(){ 
     printf("funa: pointer: %p\n\r",this); 
     globala(this); 
     globalb(this); 
    } 

    void funb(){ 
     printf("funb: pointer: %p\n\r",this); 
     globala(this); 
     globalb(this); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    concrete ac; 
    ac.funa(); 
    ac.funb(); 
    return 0; 
} 

output di questo programma dà:

funa: pointer: 0x7ffff67261a0 
globalA: pointer: 0x7ffff67261a0 
globalB: pointer: 0x7ffff67261a8 
funb: pointer: 0x7ffff67261a0 
globalA: pointer: 0x7ffff67261a0 
globalB: pointer: 0x7ffff67261a8 

Qualsiasi aiuto per capire questo.

Grazie.

+0

Penso che la tua domanda reale sia quando e perché il valore di un puntatore cambia quando passa a una funzione che accetta un puntatore a un dif classe feroce. –

+0

Ho trovato la tua domanda molto interessante, e mi sono molto sforzato per capirlo. Ho postato una risposta estesa, con alcune figure che cercavano di spiegare il layout degli oggetti nella corrispondente (duplicata) domanda. Sentiti libero di controllarlo, potrebbe aiutarti! – sestus

risposta

5

Ho pensato che "questo" puntatore si riferisce al valore dell'oggetto classe.

Corretto. this punta sempre sull'oggetto su cui viene invocata una funzione membro.

ho potuto vedere diversi valori di "questo" puntatore

Oh, ma non sei la stampa this (in globalA e globalB). Stai stampando obj che non ha nemmeno lo stesso tipo di this.

this è di tipo concrete*. Quando lo si passa a una funzione che accetta un argomento di tipo InterfaceB*, il puntatore è implicitamente converted per l'altro tipo. La conversione è consentita poiché interfaceB è una base di concrete. Il puntatore convertito non punta più all'oggetto this, ma a un oggetto secondario di classe base. Un oggetto secondario (istanza della classe base o membro) potrebbe ma potrebbe non avere lo stesso indirizzo dell'oggetto principale. Gli oggetti secondari di un oggetto non possono condividere un indirizzo, quindi al massimo un oggetto secondario può avere lo stesso indirizzo dell'oggetto principale, tranne nel caso di empty base optimization.

0

this è un puntatore che fa riferimento all'oggetto che richiama la funzione membro.

Il tipo di this dipende dalla funzione membro.

Ad esempio per un class X, se le funzioni membro è

1) const, allora this è di tipo const X*

2) volatile, quindi this è volatile X*

altrimenti è