2009-12-01 13 views
10

Sono confuso con la parola chiave this in C++, non sono sicuro che se sto facendo la cosa giusta passando this. Ecco il pezzo di codice che sto lottando con:come passare "questo" in C++

ClassA::ClassA(ClassB &b) { 

    b.doSth(this); 
    // trying to call b's routine by passing a pointer to itself, should I use "this"? 
} 

ClassB::doSth(ClassA * a) { 
     //do sth 
} 
+0

quando si "si" in quel commento, si intende l'oggetto ClassA o l'oggetto ClassB? – Stobor

+1

Qual è esattamente la tua domanda? Cosa ti aspetti e cosa ottieni? – fserb

+0

Hai una domanda o stavi solo condividendo? –

risposta

2

In questo caso utilizzando this passerà un puntatore alla classe chiamante, che è una, a b.DoSth. Sembra che tu stia facendo bene. La parola chiave this punta sempre all'istanza della classe da cui la stai usando.

8

In C++, this è una parola chiave definita come "il puntatore all'istanza dell'oggetto corrente". Quindi il tuo codice qui sopra è corretto.

seconda della relazione di ereditarietà/composizione tra il ClassA e ClassB, ci sono modi probabilmente migliori per ottenere ciò che si sta facendo che utilizzando il puntatore this.

0

this è un puntatore all'istanza dell'oggetto, quindi ciò che si sta facendo è corretto.

Leggi this per ulteriori informazioni.

0

this è un puntatore const sul proprio oggetto. Il puntatore this non è modificabile.

ClassA::ClassA(ClassB &b) { 

     b.doSth(this); 
     // here 'this' refers to this object ie the instance of ClassA. 
     // When you pass 'this' to doSth function --> is equivalent to passing 
     // the instance of current object of ClassA. 
     // 
    } 
14

Si sta utilizzando correttamente. Il puntatore punta all'istanza dell'oggetto corrente.

class helper 
{ 
public: 
    void help(worker *pWorker) { 
      //TODO do something with pWorker . . . 
    } 

    void help2(worker& rWorker) { 
      //TODO do something with rWorker . . . 
    } 
}; 

class worker 
{ 
public: 
    void dowork() { 
      //this one takes a worker pointer so we can use the this pointer. 
      helper.help(this); 

      //to pass by reference, you need to dereference the this pointer. 
      helper.help2(*this); 
    } 
    helper helper; 
}; 

Inoltre, dicono si dichiara worker *pW = new worker(). Se si chiama uno dei metodi (dowork) sull'oggetto pW, si noterà che il puntatore this e pW hanno lo stesso valore esatto (sono entrambi lo stesso indirizzo).

(non l'ho verificato per assicurarsi che si sviluppi, ma penso che dovrebbe).

5

È perfettamente OK passare "questo" o "* questo" come si fa.

Pericoli

Corso della vita:

Un punto circa l'esempio che hai fornito è che si sta chiamando doSth dal costruttore di ClassA. L'oggetto che è passato a doSth è forse un oggetto parzialmente costruita:

class ClassC { 
public: 
    ClassC() 
    : m_c() 
    {} 
    int m_c; 
}; 

class ClassA : public ClassC { 
public: 
    ClassA (ClassB & b) 
    : ClassC() 
    , m_b (b.doSth (this)) // ClassC constructed 
          // ClassA members partially init. 
    { 
    b.doSth (this);   // ClassA members initialized 
    } 

    // ... 
    int m_a; 
}; 

class ClassD : public ClassA { 
public: 
    ClassD(ClassB & b) 
    : ClassA (b)    // Partially init 
    , m_d() 
    { 
          // ClassC and ClassA constructed 
          // ClassD members initialized 
    } 
    int m_d; 
}; 

Ci possono essere problemi se doSth usi membri che non sono ancora state inizializzate:

void ClassB::doSth (ClassA * a) { 
    int i = a->m_c;  // OK m_c is initialized 

    int j = a->m_a;  // Not OK, m_a not initialized when called 
         // from member initialization list. 

    int k = static_cast<ClassD*> (a).m_d; // Not OK 
} 

Usando il tipo dinamico dell'oggetto :

Infine, qualsiasi utilizzo del tipo dinamico dell'oggetto (ad esempio chiamate virtuali, dynamic_cast, typeid) avrà risultati diversi su un partiall y oggetto costruito rispetto a un oggetto completo (e in alcuni casi è possibile avere un comportamento non definito).

void ClassB::doSth (ClassA * a) { 
    if (ClassD * d = dynamic_cast<ClassD *> (a)) 
    { 
    // Never true when called from ClassA::ClassA 
    } 
} 
Problemi correlati