jackhab
jackhab

Reputation: 17698

How to get C++ object name in run time?

Can I get an object's name in run time (like getting an object's type via RTTI)? I want the object to be able to print its name.

Upvotes: 17

Views: 32383

Answers (9)

AKUMA no ONI
AKUMA no ONI

Reputation: 11829

As already stated by others, you cannot actually get the name of an object during runtime. I wouldn't go so far as to say objects don't have names, like some other answers claim. Obviously we name objects all the time using variable names. The problem is, that level of abstraction doesn't exist during runtime. Those names only exist long enough for you to communicate with the compiler via your source code. One compilation is complete, your code is executed, and at that point objects are only referenced by their location in memory.

You can have a macro save the name of an object during compilation though. This means that you won't be able to have a newly instantiated objects constructor save its own name, but outside of the class you can save the name you gave to it. In other words...



You CANNOT do anything like this:

  class Foo {
     public:
     foo(){
        this->objName = getObjNameSomeHow();
     }

     string objName
  }


However, you can do the following (via a macro):

  // Macro
  #define GET_OBJECT_NAME(obj) #obj 

  // Includes
  #include <iostream>
  #include <string>

  using namespace std;

  int main() { 
    string obj_name = GET_OBJECT_NAME(MyObject); 

    cout << "The object name is: " << obj_name << std::endl; 

    return 0;
  }

I don't know if the macro above wasn't available back when this question was originally posted, (or when most of the other answers were authored), but I feel like the above is a better solution than the other answers here.


Another Possible Solution:

Using the __func__ from inside of the constructor.

It will get you the class's name if you use it from the constructor.

There is already an answer that covers using __func__ for a simlar question here.

Upvotes: 0

Greg C.
Greg C.

Reputation: 1

So, this is basically what I did. It's hacky, but it does the trick. I created a variadic macro that takes advantage of stringizing. Unfortunately, it becomes clumsy with the need for a _dummy parameter in order to provide the pseudo-default ctor, because you cannot omit the comma separating the named argument from the variable arguments (I even tried with gnu cpp, but was unsucessful--may I didn't try hard enough).

#include <string>

#define MyNamedClass( objname, ... ) MyClass objname(__VA_ARGS__, #objname )

class MyClass
{
public:
   MyClass( void* _dummy=nullptr, const std::string& _name="anonymous") : name( _name ) {}
   MyClass( int i, const std::string& _name="anonymous" ) : name( _name ) {}

private:
   std::string name;
};


int main()
{
   MyClass mc0;
   MyClass mc1(54321);
   MyNamedClass( mc2, nullptr);
   MyNamedClass( mc3, 12345 );

   return 0;
}

Upvotes: 0

KeithB
KeithB

Reputation: 17017

Its not possible. For on thing, an object doesn't have a unique name.

A a;
A& ar = a;  // both a and ar refer to the same object

new A;  // the object created doesn't have a name

A* ap = new A[100];  // either all 100 objects share the same name, or need to 
                     // know that they are part of an array.

Your best bet is to add a string argument to the objects constructor, and give it a name when its created.

Upvotes: 11

zaratustra
zaratustra

Reputation: 8738

C++ objects don't have 'names' (unless I am understanding the problem wrong) Your best hope is to name them as you make them.

class NamedObject
{
  String name;
  NamedObject(String argname)
  { 
    name = argname;
  }
}

NamedObject phil("phil");

Upvotes: 2

Tom
Tom

Reputation: 10819

This may be GCC-specific:

#include <typeinfo>
#include <iostream>

template <typename T>
void foo(T t)
{
    std::cout << typeid(t).name() << std::endl;
}

Upvotes: 5

Loki Astari
Loki Astari

Reputation: 264381

The language does not give you access to that information.
By the time the code has been compiled all named objects have been translated into relative memory locations. And even these locations overlap because of optimization (ie once a variable is no longer in use its space can be used by another variable).

The information you need is stored in the debug symbols that are generated by most compilers but these are usually stripped from release versions of the executable so you can not guarantee they exist.

Even if the debug symbols existed they are all compiler/platform specfic so your code would not be portable between OS or even compilers on the same OS. If you really want to follow this course you need to read and understand how the debugger for your platform works (unless you have already written a compiler this is very non trivial).

Upvotes: 5

Simon B. Jensen
Simon B. Jensen

Reputation: 978

C++ doesn't really support reflection. However, a bit of googling produced a couple of alternate methods, I doubt you will find them useful though.

Upvotes: 2

jpalecek
jpalecek

Reputation: 47762

Since objects in C++ don't have any names, you cannot get them. The only thing you can get to identify an object is its address.

Otherwise, you can implement your naming scheme (which means the objects would have some char* or std::string member with their name). You can inspire yourself in Qt with their QObject hierarchy, which uses a similar approach.

Upvotes: 16

tunnuz
tunnuz

Reputation: 23978

If you mean the name of the variable, I don't think this is possible. Maybe if you compile with the GNU Debugger option on ... but even in that way I don't think the language have constructs to do that.

Upvotes: 1

Related Questions