2011-10-21 8 views
11

In un sistema in cui gli oggetti registrati devono avere nomi univoci, voglio utilizzare/includere il puntatore this dell'oggetto nel nome. Voglio che il modo più semplice per creare ??? dove:Converti il ​​puntatore "questo" nella stringa

std::string name = ???(this);

+0

convertirlo come stringa esadecimale che rappresenta l'indirizzo? –

+0

Vedere la risposta a questa domanda: http://stackoverflow.com/questions/1255366/how-can-i-append-data-to-a-stdstring-in-hex-format – tenfour

+1

suona come una cattiva idea: tu ' ri legando l'identità dell'oggetto con la sua posizione di memoria: cosa succede se provi a spostarlo in una versione futura della tua applicazione? Il tuo codice si romperà in modi molto spiacevoli. – akappa

risposta

23

Si potrebbe utilizzare rappresentazione di stringa dell'indirizzo:

#include <sstream> //for std::stringstream 
#include <string> //for std::string 

const void * address = static_cast<const void*>(this); 
std::stringstream ss; 
ss << address; 
std::string name = ss.str(); 
+0

Ho provato senza il cast a void *, e ha funzionato anche. È necessario per alcune ragioni? – Willy

+2

'ss << questo' potrebbe richiamare l'operatore <<' che accetta 'T const * const' come argomento, nel qual caso non si otterrà l'indirizzo come stringa. Ecco cosa intendo: http://coliru.stacked-crooked.com/a/cded799e93012de6 – Nawaz

2

Si potrebbe utilizzare ostringstream l'indirizzo di questo puntatore e mettere il valore di quel ostringstream come stringa?

4
#include <sstream> 
#include <iostream> 
struct T 
{ 
    T() 
    { 
     std::ostringstream oss; 
     oss << (void*)this; 
     std::string s(oss.str()); 

     std::cout << s << std::endl; 
    } 
}; 

int main() 
{ 
    T t; 
} 
5

Intendi formattare il puntatore stesso come una stringa?

std::ostringstream address; 
address << (void const *)this; 
std:string name = address.str(); 

Oppure ... sì, tutte le altre risposte equivalenti nel tempo impiegato per digitare questo!

-1

In un sistema in cui gli oggetti registrati devono avere nomi univoci, voglio utilizzare/includere questo puntatore dell'oggetto nel nome.

L'indirizzo di un oggetto non è necessariamente univoco. Esempio: si assegna dinamicamente un tale oggetto, lo si usa per un po ', lo si elimina e quindi si assegna un altro oggetto di questo tipo. L'oggetto appena assegnato potrebbe avere lo stesso indirizzo dell'oggetto del precedente.

Ci sono modi molto migliori per generare un nome univoco per qualcosa. Un contatore gensym, ad esempio:

// Base class for objects with a unique, autogenerated name. 
class Named { 
public: 
    Named() : unique_id(gensym()) {} 
    Named(const std::string & prefix) : unique_id(gensym(prefix)) {} 

    const std::string & get_unique_id() { return unique_id; } 

private: 
    static std::string gensym (const std::string & prefix = "gensym"); 
    const std::string unique_id; 
}; 

inline std::string Named::gensym (const std::string & prefix) { 
    static std::map<std::string, int> counter_map; 
    int & entry = counter_map[prefix]; 
    std::stringstream sstream; 
    sstream << prefix << std::setfill('0') << std::setw(7) << ++entry; 
    return sstream.str(); 
} 

// Derived classes can have their own prefix. For example, 
class DerivedNamed : public Named { 
public: 
    DerivedNamed() : Named("Derived") {} 
}; 
+1

Ma una volta che il primo oggetto è stato distrutto, non esiste. Quindi l'indirizzo è unico ... se distruggo il primo oggetto, è anche non registrato dalla struttura dei dati che richiede un nome. –