Convert "this" pointer to string
Asked Answered
C

7

27

In a system where registered objects must have unique names, I want to use/include the object's this pointer in the name. I want the simplest way to create ??? where:

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

Caper answered 21/10, 2011 at 13:31 Comment(12)
convert it as an hex string representing the address ?Wiredraw
See the answer to this question: #1255866Aldous
sounds like a bad idea: you're tying object's identity with its memory location: what if you try to move it in a future version of your application? Your code will break in very unpleasant ways.Bounteous
Agree, if what you want is to have unique name for each object, just assign a different string in constructor of your class.Diddle
What is the output you'd like to see?Maskanonge
If your application can have multiple instances, your method could fail because difference instances may have the same (virtual) address.Diddle
I agree with akappa. This sounds like a bad idea.Shingle
@EricZ, even simpler, simpler delete then new in one instance and you could get the same address.Kilohertz
That's true. But for a delete-then-new object, its address is unlikely to be conflicted w/ the address of another existing object, which is what OP asks, right?Diddle
why WHY WHY - Why do you want to go down this daft route?Hair
If my application has multiple instances, they are separate and it doesn't matter if they're only unique within each instance... not like running under the JVM.Caper
"just assign a different string in constructor of your class" - not sure how that helps really. Still have to get the strong from somewhere, and adding a new arg to every class seems a bit cumbersome... this is a simple scenario only where a 3rd-party library will throw if you try to register a non-unique name. So the name doesn't have to match the memory address, it's just a cheap trick because I know every instance of type T currently in existence will have different addresses... I don't use the address string otherwise, only internally.Caper
K
53

You could use string representation of the address:

#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(); 
Kincaid answered 21/10, 2011 at 13:34 Comment(3)
I tested without the cast to void*, and it worked too. Is it necessary for some reasons ?Bowline
ss << this might invoke operator<< which accepts T const * const as argument, in which case you'll not get the address as string. Here is what I mean : coliru.stacked-crooked.com/a/cded799e93012de6Kincaid
A simpler one-liner that doesn't require a whole stringstream: std::string address = std::to_string((unsigned long long)(void**)this);, which also works if you need the address as an integer, not a string: unsigned long long address = (unsigned long long)(void**)this;Prop
T
10

You mean format the pointer itself as a string?

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

Or ... yes, all the other equivalent answers in the time it took me to type this!

Thermae answered 21/10, 2011 at 13:36 Comment(0)
P
8

A simpler one-liner that doesn't require a whole stringstream:

std::string address = std::to_string((unsigned long long)(void**)this);

Also implied, works with pointers of any time, not just this. Also works if you just need it as an integer:

unsigned long long address = (unsigned long long)(void**)this;

You can replace unsigned long long with a type alias that is provided by the system. On Windows it's uintptr_t.

Prop answered 20/4, 2023 at 16:28 Comment(0)
H
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;
} 
Hoebart answered 21/10, 2011 at 13:35 Comment(0)
C
2

You could use ostringstream the this pointer's address and put that ostringstream's value as string?

Callison answered 21/10, 2011 at 13:33 Comment(0)
S
0

In a system where registered objects must have unique names, I want to use/include the object's this pointer in the name.

An object's address is not necessarily unique. Example: You dynamically allocate such an object, use it for a while, delete it, and then allocate another such object. That newly allocated object might well have the same the object address as the previous.

There are far better ways to generate a unique name for something. A gensym counter, for example:

// 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") {}
};  
Shingle answered 21/10, 2011 at 14:44 Comment(1)
But once the first object is destroyed, it doesn't exist. So the address IS unique... if I destroy the first object, it is also unregistered from the data-structure requiring a name.Caper
P
0

A simple and explicit way to convert a pointer into a string:

std::string str = std::to_string(reinterpret_cast<uintptr_t>(ptr));
Privative answered 15/3 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.