2013-02-11 17 views
38

Come posso decidere se ho bisogno di addressof(x) invece di &x quando si prende l'indirizzo di un oggetto?Quando utilizzare addressof (x) invece di & x?


sembra la questione era confusa, così una precisazione è in ordine:

addressof bypassa ovviamente l'operatore di indirizzo sovraccarico. Ne sono già consapevole.

Quello che voglio sapere è:
Come faccio a sapere se questo è quello che voglio veramente fare? (Soprattutto quando all'interno di un modello, ecc.)

C'è qualche tipo di "regola" che mi aiuta a capire quando ho bisogno di addressof anziché &?
Dopo tutto, entrambi restituiscono "l'indirizzo di" l'oggetto, quindi quando devo usare quale?

risposta

52

Si utilizza std::addressof quando è necessario. Tristemente, "quando devi" include ogni volta che lavori nel codice del modello e vuoi trasformare una variabile di tipo sconosciuto T o T& in un puntatore onesto a Dio sulla memoria di quella variabile.

Poiché il comitato C++ ha scioccamente permesso l'overloading dell'operatore di riferimento (a scopo legittimo), è possibile per un utente creare un'istanza del modello con un tipo che non è possibile utilizzare l'operatore di riferimento per ottenere un puntatore effettivo a. std::addressof è un modo per aggirare gli utenti che utilizzano questa discutibile funzionalità C++ per fare ciò per cui la lingua dovrebbe essere garantita per iniziare.

In breve, è una correzione di libreria per una stupidità della lingua. Usalo nel codice del modello invece di & se vuoi assicurarti che gli utenti non possano violare il tuo codice. Se i tuoi utenti possono fidarsi di non utilizzare questa funzionalità il-concepita, allora puoi usare &.

+4

+1 migliore risposta che ho visto finora, spiega molto bene la situazione. – Mehrdad

+1

Quello che trovo divertente è che la * una * classe I * prevista * per sovraccaricare l'indirizzo di, 'reference_wrapper', non sembra ... – Mehrdad

+1

@Mehrdad: Questo non mi sorprende; sia 'reference_wrapper' che' addressof' provengono da Boost. AKA: le persone che più conoscono i pericoli di sovraccaricare quell'operatore. –

5

Da utilizzare quando si desidera conoscere l'indirizzo effettivo dell'oggetto e non il risultato di un sovraccarico di indirizzo operator&.

+0

Ciò non vanifica lo scopo del sovraccarico dell'operatore? – Mehrdad

+0

@Mehrdad Forse - ma puoi scegliere se vuoi il sovraccarico o meno. – nos

+0

@Mehrdad Se ti fidi di tutti per implementare un bel 'operatore &' s. –

7

Se è un tipo definito dall'utente con unario unificato operator& e si desidera il relativo indirizzo, utilizzare addressof.

Direi che dovresti sempre usare & perché, come dici tu, se non lo fai, sconfigge lo scopo del sovraccarico. Salvo ovviamente fai qualcosa di significativo con il sovraccarico, nel qual caso avresti bisogno di addressof (fuori dalla classe, all'interno puoi semplicemente usare this), ma devi essere molto sicuro di quello che stai facendo.

Ecco di più - se si vuole sovraccaricare operator& al di fuori della classe (è possibile), si necessario uso addressof per restituire l'indirizzo, altrimenti si traduce in una ricorsione infinita:

struct Class 
{ 
    virtual ~Class() {} 
    int x; 
}; 

void* operator&(const Class& x) 
{ 
    //return &x; <---- infinite recursion 
    return addressof(x) + 4; //I know this isn't safe 
          //but I also know the intrinsics of my compiler 
          //and platform to know this will actually return 
          //the address to the first data member 
} 

lo so questo non è sicuro.

+0

Non sarebbe forse completamente vanificato lo scopo dell'operatore sovraccarico? Come posso dire se dovrei sconfiggerlo o no? – Mehrdad

+0

@Mehrdad vedi modifica. –

+0

Hmm, quindi questa è una situazione in cui io * non posso * nemmeno usare '&' in primo luogo, il che rende la domanda discutibile! – Mehrdad

6

La mia opinione solo:

meno che non sono parte del team di progettazione la classe e la sua interfaccia, mai. Personalmente non ho mai visto una buona ragione per sovraccaricare quell'operatore. Ma se qualcuno progetta una classe in cui ha senso, e supponendo che la classe sia destinata al consumo pubblico (vale a dire, la classe non è per uso interno solo in una particolare libreria), mi aspetto che la classe funzioni in codice normale naturalmente si aspetta che & significhi "indirizzo di". Se la classe che sovraccarica l'operatore non è progettata in modo così sensibile, allora non userei quella classe, periodo. Perché o quella classe è rotta, o non è pensata per essere usata al di fuori della biblioteca di cui fa parte.

4

Dopo tutto, entrambi restituiscono "l'indirizzo di" l'oggetto, quindi quando si utilizza quale?

Non hai assolutamente alcuna garanzia che un sovraccarico operator& è il "indirizzo" l'oggetto, è probabile che non lo è, o l'autore della classe probabilmente non si sarebbero preoccupati di sovraccaricarlo. Potrebbero averlo sovraccaricato per restituire un tipo diverso, o anche per restituire void se stanno tentando di impedire alle persone di prendere il suo indirizzo.

Se si desidera un puntatore ad un oggetto che potrebbe hanno sovraccaricato & (ad esempio perché il suo tipo è un parametro di template in modo da non si sa) quindi utilizzare std::addressof o documento che il modello non supporta i tipi che non restituire l'indirizzo reale dell'oggetto come il tipo giusto.