我可以在运行时获取对象的名称(例如通过 RTTI 获取对象的类型)吗?我希望对象能够打印其名称。
8 回答
由于 C++ 中的对象没有任何名称,因此您无法获取它们。您唯一可以识别对象的是它的地址。
否则,您可以实现您的命名方案(这意味着对象将有一些char*
或std::string
带有其名称的成员)。您可以在 Qt 中使用他们的 QObject 层次结构来启发自己,它使用了类似的方法。
这是不可能的。事实上,一个对象没有唯一的名称。
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.
最好的办法是向对象构造函数添加一个字符串参数,并在创建时为其命名。
这可能是 GCC 特定的:
#include <typeinfo>
#include <iostream>
template <typename T>
void foo(T t)
{
std::cout << typeid(t).name() << std::endl;
}
该语言不允许您访问该信息。
到编译代码时,所有命名对象都已转换为相对内存位置。甚至这些位置由于优化而重叠(即一旦一个变量不再使用,它的空间可以被另一个变量使用)。
您需要的信息存储在大多数编译器生成的调试符号中,但这些通常从可执行文件的发布版本中剥离,因此您不能保证它们存在。
即使存在调试符号,它们都是编译器/平台特定的,因此您的代码不能在操作系统之间移植,甚至不能在同一操作系统上的编译器之间移植。如果你真的想学习这门课程,你需要阅读并理解你平台的调试器是如何工作的(除非你已经编写了一个编译器,这是非常重要的)。
C++ 并不真正支持反射。然而,一些谷歌搜索产生了一些替代方法,但我怀疑你会发现它们有用。
如果您的意思是变量的名称,我认为这是不可能的。也许如果您使用 GNU Debugger 选项编译...但即使这样,我也不认为该语言具有执行此操作的构造。
C++ 对象没有“名称”(除非我对问题的理解是错误的)您最好的希望是在创建它们时命名它们。
class NamedObject
{
String name;
NamedObject(String argname)
{
name = argname;
}
}
NamedObject phil("phil");
所以,这基本上就是我所做的。这很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;
}