Retrieving a C++ Class Name Programmatically

Retrieving a c++ class name programmatically

You can use typeid:

#include <typeinfo>

std::cout << typeid(obj).name() << "\n";

However, the type name isn't standardided and may differ between different compilers (or even different versions of the same compiler), and it is generally not human readable because it is mangled.

On GCC and clang (with libstdc++ and libc++), you can demangle names using the __cxa_demangle function (on MSVC demangling does not seem necessary):

#include <cxxabi.h>
#include <cstdlib>
#include <memory>
#include <string>

std::string demangle(char const* mangled) {
auto ptr = std::unique_ptr<char, decltype(& std::free)>{
abi::__cxa_demangle(mangled, nullptr, nullptr, nullptr),
std::free
};
return {ptr.get()};
}

This will still not necessarily be a readable name — for instance, std::string is a type name for the actual type, and its complete type name in the current libstdc++ is std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >; by contrast, in the current libc++ it’s std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >. “Prettifying” type aliases is unfortunately not trivial.

How can I get the class name from a C++ object?

You can display the name of a variable by using the preprocessor. For instance

#include <iostream>
#define quote(x) #x
class one {};
int main(){
one A;
std::cout<<typeid(A).name()<<"\t"<< quote(A) <<"\n";
return 0;
}

outputs

3one    A

on my machine. The # changes a token into a string, after preprocessing the line is

std::cout<<typeid(A).name()<<"\t"<< "A" <<"\n";

Of course if you do something like

void foo(one B){
std::cout<<typeid(B).name()<<"\t"<< quote(B) <<"\n";
}
int main(){
one A;
foo(A);
return 0;
}

you will get

3one B

as the compiler doesn't keep track of all of the variable's names.

As it happens in gcc the result of typeid().name() is the mangled class name, to get the demangled version use

#include <iostream>
#include <cxxabi.h>
#define quote(x) #x
template <typename foo,typename bar> class one{ };
int main(){
one<int,one<double, int> > A;
int status;
char * demangled = abi::__cxa_demangle(typeid(A).name(),0,0,&status);
std::cout<<demangled<<"\t"<< quote(A) <<"\n";
free(demangled);
return 0;
}

which gives me

one<int, one<double, int> > A

Other compilers may use different naming schemes.

C# getting its own class name

Try this:

this.GetType().Name

Get Current Class Name

An instance would exactly be "current", the concept does not make much sense otherwise. If you just want the name of a known type that would be typeof(Class).Name.

Java - get the current class name?

The "$1" is not "useless non-sense". If your class is anonymous, a number is appended.

If you don't want the class itself, but its declaring class, then you can use getEnclosingClass(). For example:

Class<?> enclosingClass = getClass().getEnclosingClass();
if (enclosingClass != null) {
System.out.println(enclosingClass.getName());
} else {
System.out.println(getClass().getName());
}

You can move that in some static utility method.

But note that this is not the current class name. The anonymous class is different class than its enclosing class. The case is similar for inner classes.

Get the name of a class as a string in C#

Include requires a property name, not a class name. Hence, it's the name of the property you want, not the name of its type. You can get that with reflection.

How to get Class name that is calling my method?

You can use StackFrame of System.Diagnostics and MethodBase of System.Reflection.

StackFrame(Int32, Boolean) initializes a new instance of the StackFrame class that corresponds to a frame above the current stack frame, optionally capturing source information.

MethodBase, provides information about methods and constructors.

public static string NameOfCallingClass()
{
string fullName;
Type declaringType;
int skipFrames = 2;
do
{
MethodBase method = new StackFrame(skipFrames, false).GetMethod();
declaringType = method.DeclaringType;
if (declaringType == null)
{
return method.Name;
}
skipFrames++;
fullName = declaringType.FullName;
}
while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));

return fullName;
}

Your logger classes call this method:

public static void Error()
{
string name = NameOfCallingClass();
}

Dynamically calling method and class name

How to create an instance of a type from its string representation:

string scenario1 = "TheNamespace.MockScenario1";
Type theType = this.GetType().Assembly.GetType(scenario1);
var theInstance = (MockScenario1)Activator.CreateInstance(theType);
theInstance.GetInfo();

It will be better if your classes implement a common interface, for example IGetInfoAware, and then you could write a more generic loader:

var theInstance = (IGetInfoAware)Activator.CreateInstance(theType);

Note: you need to provide the full class name for scenario1 and scenario2

See Activator.CreateInstance

EDIT:

As @Georg pointed out, if the type is not declared in the assembly of the context objects, then it is necessary first to get the assembly where the type is hosted:

var theAssembly = (
from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()
where (assembly.FullName == "TheNamespace.AssemblyName")
select assembly
)
.FirstOrDefault();

if ( theAssembly!= null ){
Type theType = theAssembly.GetType(scenario1);
var theInstance = (IGetInfoAware)Activator.CreateInstance(theType);
theInstance.GetInfo();
}

If for some reason the assembly name is unknown to you, then the type could be resolved like the following:

public Type GetTypeFromString(String typeName)
{
foreach (Assembly theAssembly in AppDomain.CurrentDomain.GetAssemblies())
{
Type theType = theAssembly.GetType(typeName);
if (theType != null)
{
return theType;
}
}
return null;
}

How can I get the name of NameSpace and Class dynamically in C#?

You should use the GetType() method on your A object.

namespace nmspA {
public class A{
private void DoSomething(){
B.Foo(this);
}
}
}

namespace nmspB {
public class B {
public static void Foo(A a){
Debug.Write(a.GetType()); // Will write : "nmspA.A"
}
}
}

C# Reflection: How to get class reference from string?

You will want to use the Type.GetType method.

Here is a very simple example:

using System;
using System.Reflection;

class Program
{
static void Main()
{
Type t = Type.GetType("Foo");
MethodInfo method
= t.GetMethod("Bar", BindingFlags.Static | BindingFlags.Public);

method.Invoke(null, null);
}
}

class Foo
{
public static void Bar()
{
Console.WriteLine("Bar");
}
}

I say simple because it is very easy to find a type this way that is internal to the same assembly. Please see Jon's answer for a more thorough explanation as to what you will need to know about that. Once you have retrieved the type my example shows you how to invoke the method.



Related Topics



Leave a reply



Submit