假设我们有一个MyClass类和一个memberfunc()。 为这个MyClass创建了一个对象,比如ObjA。
i.e MyClass ObjA;
ObjA调用memberfunc()。
我们可以以编程方式在memberfunc()中获得此名称'ObjA'吗?
注意:我知道如何使用RTTI(运行时类型识别)获取对象的类型,即“MyClass”,下面的radman也解释了相同的内容。
修改
如果在c ++中这是不可能的,是否可以使用任何其他编程语言?
EDIT2
对这个问题进行了一些修改,因为很少有人无法解释。
答案 0 :(得分:8)
这里有几个问题:
我已经看到C ++库破解了堆栈(顺便说一句,这是非常不便携的),因此让代码能够像“谁叫我?”这样的东西。但是我已经多年没用过那些东西了。
答案 1 :(得分:3)
不,没有办法。 C ++没有反射, 可能会使这成为可能。在第二个想法,甚至是例如反射设施。 Java没有此功能。
C ++直接编译为机器代码,不再包含源代码中的任何标识符。您当然可以将“变量名称”存储在成员字段中(前提是该对象在单个名称下引用...)。
答案 2 :(得分:3)
不,对象名称仅存在于源代码中。编译后,对象引用只是一个内存偏移量。如果你想知道变量名,你必须在某处描述它。
在具有内省机制(例如Reflection)的语言中获取变量名称的工具非常有限,并且根本没有广泛使用。即使在C#(少女语言)中,要获得变量名称,您需要使用一种称为投影的古怪C#3.5特征,然后跳过箍来提取它。即使这样,你也必须为它编程 - 它不会在代码的任何一点都可用。
在一些人认为你正在构建的问题 - 从成员函数中获取对象的名称 - 理论上不可能。请考虑以下情况:
class ObjA {
public:
void memberfunc() {
//confused??? instance1 or instance2?
}
};
//main
ObjA instance1;
ObjA* instance2 = &instance1;
instance2->memberfunc();
在上面的示例中,我们有一个ObjA
实例,其中有两个变量指向它(我在这里使用了术语指向而非常松散)。这些变量完全超出对象的任何可想象的控制范围,因此即使获得变量名称的工具可用,也无法获得它们。
在C#中,您可以使用匿名类和Reflection来获取变量名。这样做的方法很尴尬,如果你试图用它来向别人展示一些东西,现在就放弃,因为你们两个都会感到困惑。该技术使用了一些主流编程新功能,包括匿名类,投影,扩展方法和反射。
public static class Extensions {
public static string GetFirstPropertyName(this object obj) {
return obj.GetType().GetProperties()[0].Name;
}
}
public class Program {
public static void Main() {
int intVal = 5;
var name = (new {intVal}).GetFirstPropertyName();
//name=="intVal"
}
}
答案 3 :(得分:0)
那么你的问题似乎有点不清楚,但假设你想在其中一个成员函数中打印出类的名称,那很可能。
您需要使用的是typeid命令。这在运行时为类类型的对象提取了一个接近人类可读的名称。但是你不能依赖这个名称在不同平台上保持一致,即你得到的名称可能因平台而异(我从下面的示例代码得到的是'4ObjA'。
#include <iostream>
#include <typeinfo>
class ObjA
{
public:
void memberfunc()
{
std::cout << typeid(*this).name() << std::endl;
}
};
int main(int argc, char **argv)
{
ObjA obj;
obj.memberfunc();
}
答案 4 :(得分:0)
您的问题并不完全清楚 - 您想知道该方法所属的对象吗?或者调用成员函数的方法的名称? Oo别的什么..?
在大多数面向对象语言中,您可以非常轻松地获取当前类的名称:
class Myclass(object):
def memberfunc(self):
print self.__class__.__name__
obja = Myclass()
obja.memberfunc() # prints Myclass
你不能明智地将obja
标识符作为名称(几乎所有语言),我不明白为什么你想要(在这种情况下,你会使用某种类型的键/值映射)
如果要获取调用该方法的方法的名称,则必须检查调用堆栈,例如在Python中使用inspect
方法:
import inspect
class Myclass(object):
def memberfunc(self):
current_call = inspect.stack()[0]
previous = inspect.stack()[1]
print previous[3]
def somefunc():
obja = Myclass()
obja.memberfunc() # prints somefunc
somefunc()
我想这在其他语言中并不那么容易
同样,你想要做这种事情的情况很少见,通常仅限于内省重要的事情,如代码覆盖工具和调试器
答案 5 :(得分:0)
正如其他帖子所述,没有直接的方法来访问您在运行时在代码中选择的变量名称标识符 - 从机器的角度来看根本不需要它。但是,在Ruby中,根据结构来了解调用者的详细信息是微不足道的:
class Foo
def foo
puts self.class
end
end
class Bar < Foo
end
f = Foo.new
b = Bar.new
f.foo #=> Foo
b.foo #=> Bar
您可以使用typeid
在C ++中执行类似操作,但这并不完全正确。例如:
#include <iostream>
class Foo {
public:
void foo () { std::cout << typeid(this).name() << std::endl; }
};
int main () {
Foo f;
f.foo (); // on my system returns P3Foo
return 0;
}
答案 6 :(得分:0)
这有点像黑客,但您可以使用宏来存储类标识符名称。这就是我的意思:
#include <iostream>
#include <string>
#define createMyClass(x) MyClass x("x")
class MyClass{
string _name;
MyClass( const string& name ) : _name(name){}
memberfunc(){
std::cout << "Name: " << _name << std::endl;
}
}
int main (int argc, char **argv) {
createMyClass( ObjA );
ObjA.memberfunc(); // prints the name
return 0;
}