Come e quando usare correttamente * questo puntatore e la congruenza argomento?
-
26-09-2019 - |
Domanda
Quando vado attraverso il codice scritto da collega, in certo luogo, usano:
this->doSomething(); //-->case A
doSomething(); //-->case B
In realtà io non sono sicuro circa il grande utilizzo di questo puntatore * ...: (
Un altro problema con la corrispondenza argomento:
obj.doOperation(); //-->case C
(&obj)->doOperation(); //-->case D
In realtà entrambi i casi stanno effettuando l'operazione desiderata, è semplicemente un modo per rendere il codice aspetto più complesso?
Qual è la sua raccomandazione su questi due domanda? Quando è il momento opportuno per usarli e perché?
Soluzione
Questa non è una risposta alla tua domanda, ma una nota che entrambi i frammenti possono fare cose diverse:
namespace B { void doSomething() {} }
struct A {
void f()
{
using B::doSomething;
this->doSomething(); // call A::doSomething
doSomething(); // calls B::doSomething
}
int a;
void g(int a)
{
this->a = a; // assigns argument to member
}
A* operator & () { return this; }
void doOperation() {}
void doSomething() {}
};
void g(A &obj)
{
obj.doOperation(); // calls A::doOperation directly
(&obj)->doOperation(); // calls A::operator & first
}
Altri suggerimenti
I casi B e C sono sempre il modo appropriato. I casi A e D sono equivalenti e non fare nulla di diverso.
A pochi eccezioni a questo:
- Se la classe ha un
operator&
overload che fa le cose sorprendenti, poi caso D potrebbe fare qualcosa di diverso che C. In realtà avere classi che fanno questo non è consigliato, in quanto sarebbe essere fonte di confusione. - Se c'è un
doSomething
variabile locale (o qualcos'altro di quel nome nel campo di applicazione locale), allora A rimanda ad undoSomething
diverso da B. Anche in questo caso non è consigliabile per ottenere se stessi in una situazione del genere, meglio dare diversi nomi a cose diverse.
C e D sono diversi. Se doOperation
è virtuale, caso D eseguirà la chiamata virtuale, caso C si esegue una chiamata non virtuale se obj
non è un riferimento. Ciò presuppone, tuttavia, che operator&
e operator->
non sono stati sovraccaricati.
Io tendo ad usare A su B dal momento che ci può essere un identificatore doSomething
locale. All'interno codice del modello, le cose potrebbero peggiorare (anche se non posso venire con un esempio preciso momento). E 'una buona abitudine da prendere.