Как получить имя classа из объекта C ++?

Возможно ли получить имя объекта?

#include class one { public: int no_of_students; one() { no_of_students = 0; } void new_admission() { no_of_students++; } }; int main() { one A; for(int i = 0; i < 99; i++) { A.new_admission(); } cout<<"class"<<[classname]<<" "<<[objectname]<<"has " <<A.no_of_students<<" students"; } 

где я могу получить имена, что-то вроде

 [classname] = A.classname() = one [objectname] = A.objectname() = A 

Предоставляет ли C ++ какой-либо механизм для достижения этого?

Вы можете отобразить имя переменной с помощью препроцессора. Например

 #include  #define quote(x) #x class one {}; int main(){ one A; std::cout< 

выходы

 3one A 

на моей машине. # Изменяет токен в строку, после предварительной обработки строки

 std::cout< 

Конечно, если вы сделаете что-то вроде

 void foo(one B){ std::cout< 

ты получишь

 3one B 

поскольку компилятор не отслеживает все имена переменных.

Так как это происходит в gcc, результат typeid (). Name () - это искомое имя classа, чтобы использовать demangled версию

 #include  #include  #define quote(x) #x template  class one{ }; int main(){ one > A; int status; char * demangled = abi::__cxa_demangle(typeid(A).name(),0,0,&status); std::cout< 

который дает мне

 one > A 

Другие компиляторы могут использовать разные схемы именования.

использовать typeid(class).name

// иллюстративный код, предполагающий, что все включает / пространства имен и т. д.

 #include  #include  using namespace std; struct A{}; int main(){ cout << typeid(A).name(); } 

Важно помнить, что это дает определенные имена реализации.

Насколько я знаю, нет способа получить имя объекта во время выполнения надежно, например, «A» в вашем коде.

EDIT 2:

 #include  #include  #include  using namespace std; struct A{ }; struct B{ }; map m; int main(){ m[&typeid(A)] = "A"; // Registration here m[&typeid(B)] = "B"; // Registration here A a; cout << m[&typeid(a)]; } 

Вы хотите, чтобы [classname] был «одним» и [objectname] равным «A»?

Если это так, это невозможно. Эти имена являются только абстракциями для программиста и фактически не используются в двоичном коде, который сгенерирован. Вы можете присвоить classу статическую переменную classname, которую вы установили в «one» и обычное имя переменной objectname, которое вы бы назначили напрямую, с помощью метода или конструктора. Затем вы можете запросить эти методы для имен classов и объектов.

Чтобы получить имя classа без искажения, вы можете использовать макрос func в конструкторе:

 class MyClass { const char* name; MyClass() { name = __func__; } } 

Вы можете попробовать использовать «typeid» .

Это не работает для имени объекта, но вы знаете имя объекта, поэтому вам просто нужно его где-то хранить. Компилятору все равно, что вы назвали объект.

Однако стоит иметь в виду, что вывод typeid является спецификой для компилятора, поэтому даже если он создает то, что вы делаете на текущей платформе, он может не работать на другом. Это может быть или не быть проблемой для вас.

Другое решение – создать какую-то оболочку шаблона, в которой вы храните имя classа. Тогда вам нужно использовать частичную специализацию, чтобы заставить его вернуть правильное имя classа для вас. Это имеет преимущество рабочего времени компиляции, но значительно сложнее.

Изменить: быть более явным

 template< typename Type > class ClassName { public: static std::string name() { return "Unknown"; } }; 

Тогда для каждого classа somethign liek следующее:

 template<> class ClassName { public: static std::string name() { return "MyClass"; } }; 

Что может быть даже макросом следующим образом:

 #define DefineClassName( className ) \ \ template<> class ClassName \ { \ public: \ static std::string name() \ { \ return #className; \ } \ }; \ 

Позволяя вам просто сделать

 DefineClassName( MyClass ); 

Наконец, чтобы получить имя classа, вы должны сделать следующее:

 ClassName< MyClass >::name(); 

Edit2: в дальнейшем вы должны добавить макрос «DefineClassName» в каждый class, который вы создали, и определить функцию «имя classа», которая вызовет функцию статического шаблона.

Edit3: И подумать об этом … Очевидно, что плохое опубликование первой вещи по утрам, как вы можете, просто определить функцию-член «classname ()» следующим образом:

 std::string classname() { return "MyClass"; } 

который может быть macro’d следующим образом:

 DefineClassName( className ) \ std::string classname() \ { \ return #className; \ } 

Тогда вы можете просто просто отбросить

 DefineClassName( MyClass ); 

в class, как вы его определяете …

Просто напишите простой шаблон:

 template const char* getClassName(T) { return typeid(T).name(); } struct A {} a; void main() { std::cout << getClassName(a); } 

Улучшение для ответа @Chubsdad,

 //main.cpp using namespace std; int main(){ A a; a.run(); } //Ah class A{ public: A(){}; void run(); } //A.cpp #include  #include  void A::run(){ cout << (string)typeid(this).name(); } 

Что будет печатать:

 class A* 
  • Можем ли мы создать экземпляр абстрактного classа?
  • Передача аргументов конструктору в VBA
  • Как перетасовать и раздавать карты по одному игроку?
  • Компонент формы доступа из другого classа
  • Java: статический class?
  • Почему вызов метода в моем производном classе вызывает метод базового classа?
  • Каково значение по умолчанию для членов classа C ++
  • Размер classа (объекта) в .NET.
  • Почему у нас нет статического метода в (нестационарном) внутреннем classе?
  • Получить все classы в пути classа
  • Как class может иметь свой собственный тип, это не бесконечная recursion?
  • Interesting Posts

    Нет клавиши меню клавиатуры Windows, альтернативы?

    Как вы используете UrlEncode без использования System.Web?

    Отображается ли ваш MAC-адрес при попадании на сайт?

    Как получить IP-адрес из HTTP-заголовка в Java

    Использование Statement with Generics: использование ISet = System.Collections.Generic.ISet

    Исключить группы, которые имеют разные значения

    Как получить первую запись в каждой группе с помощью Linq

    Могу ли я зарядить свой ноутбук зарядным устройством, имеющим разные характеристики?

    Что означает список В java generics?

    Как отключить окно авто-максимизации / изменения размера (aero-snap) при приближении к краю экрана?

    Как узнать тип объекта (в Swift)?

    Пакетные переменные Windows не будут установлены

    Могу ли я использовать пакетный файл для удаления пустых столбцов в .csv

    Проверьте, существует ли событие на элементе

    Как предотвратить закрытие программ после выполнения командного файла?

    Давайте будем гением компьютера.