16

我可以在运行时获取对象的名称(例如通过 RTTI 获取对象的类型)吗?我希望对象能够打印其名称。

4

8 回答 8

15

由于 C++ 中的对象没有任何名称,因此您无法获取它们。您唯一可以识别对象的是它的地址。

否则,您可以实现您的命名方案(这意味着对象将有一些char*std::string带有其名称的成员)。您可以在 Qt 中使用他们的 QObject 层次结构来启发自己,它使用了类似的方法。

于 2009-01-22T12:46:45.217 回答
11

这是不可能的。事实上,一个对象没有唯一的名称。

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.

最好的办法是向对象构造函数添加一个字符串参数,并在创建时为其命名。

于 2009-01-22T12:47:45.357 回答
5

这可能是 GCC 特定的:

#include <typeinfo>
#include <iostream>

template <typename T>
void foo(T t)
{
    std::cout << typeid(t).name() << std::endl;
}
于 2009-01-22T13:23:07.920 回答
4

该语言不允许您访问该信息。
到编译代码时,所有命名对象都已转换为相对内存位置。甚至这些位置由于优化而重叠(即一旦一个变量不再使用,它​​的空间可以被另一个变量使用)。

您需要的信息存储在大多数编译器生成的调试符号中,但这些通常从可执行文件的发布版本中剥离,因此您不能保证它们存在。

即使存在调试符号,它们都是编译器/平台特定的,因此您的代码不能在操作系统之间移植,甚至不能在同一操作系统上的编译器之间移植。如果你真的想学习这门课程,你需要阅读并理解你平台的调试器是如何工作的(除非你已经编写了一个编译器,这是非常重要的)。

于 2009-01-22T13:18:57.040 回答
2

C++ 并不真正支持反射。然而,一些谷歌搜索产生了一些替代方法,但我怀疑你会发现它们有用。

于 2009-01-22T12:49:31.717 回答
1

如果您的意思是变量的名称,我认为这是不可能的。也许如果您使用 GNU Debugger 选项编译...但即使这样,我也不认为该语言具有执行此操作的构造。

于 2009-01-22T12:43:44.380 回答
1

C++ 对象没有“名称”(除非我对问题的理解是错误的)您最好的希望是在创建它们时命名它们。

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

NamedObject phil("phil");
于 2009-01-22T13:26:10.817 回答
0

所以,这基本上就是我所做的。这很hacky,但它可以解决问题。我创建了一个利用字符串化的可变参数宏。不幸的是,由于需要 _dummy 参数来提供伪默认 ctor,它变得笨拙,因为您不能省略将命名参数与变量参数分开的逗号(我什至尝试使用 gnu cpp,但没有成功——可能我不够努力)。

#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;
}
于 2017-03-06T01:02:44.357 回答