C++类构造函数可以知道它的实例名称吗?

Ada*_*sey 15 c++ constructor class instance

是否可以从类方法中知道对象实例名称/变量名称?例如:

#include <iostream>

using namespace std;

class Foo {
     public:
          void Print();
};

void Foo::Print() {
     // what should be ????????? below ?
     // cout << "Instance name = " << ?????????;
}

int main() {
    Foo a, b;
    a.Print();
    b.Print();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

GMa*_*ckG 27

不可以.变量名是针对程序员的,编译器可以看到地址.

提供有关其程序的元数据/反射的其他语言可能提供此功能,C++不是这些语言之一.


Ste*_*ith 25

不是语言本身,但你可以编写类似的东西:

#include <iostream>
#include <string>

class Foo
{
 public:
    Foo(const std::string& name) { m_name = name;}
    void Print() { std::cout << "Instance name = " << m_name << std::endl; }

  private:
    std::string m_name;
};

int main() 
{
    Foo a("a");
    Foo b("b");

    a.Print();
    b.Print();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Sve*_*lov 16

编译代码中不存在变量名称.

但是,您可以使用一些#define来获取预处理中的名称,并在编译之前填充名称.

像这样的东西:

#define SHOW(a) std::cout << #a << ": " << (a) << std::endl
// ...
int i = 2;
SHOW (i);
Run Code Online (Sandbox Code Playgroud)


Luc*_*tte 9

那是什么意思?

void f(T const& p) {
    cout << p.name();
}

T r() {
    T c;
    return c;
}

void g() {
    T a;
    cout << a.name();
    T & b = a;
    cout << b.name();
    T * ptr = &b; 
    cout << ptr->name();

    T d = r();
    cout << d.name();
}
Run Code Online (Sandbox Code Playgroud)

你会期待什么?每次"一次"?那么c/d呢?


sha*_*oth 8

变量名称无法在编译后继续存在.您可以做的最好的事情是将变量名称传递给对象构造函数,并使用宏将其存储在对象中.后者将导致非常丑陋的代码,所以你只想把它作为最后的手段.


otc*_*otc 8

对于赏金:这是我曾经创造过的最大和最恶心的黑客之一,但在我看来它足以满足调试需求

#include <iostream>

#include <typeinfo>
#define DEBUG_INSTANCE( classtype, name ) class _ ## classtype ## _INSTANCE_ ## name ## _  : public classtype \
    { \
        public: \
            _ ## classtype ## _INSTANCE_ ## name ## _ (){ } \
    }; \
_ ## classtype ## _INSTANCE_ ## name ## _ name

class Foo {
public:
    virtual void _MakeTypeIDRunTime() { }
    // A virtual method in the class forces typeid(*this) to be used runtime rather than compiled
    // See: https://stackoverflow.com/a/6747130/1924602

    void Print();
};

void Foo::Print() {
    std::cout << "Instance name = " << typeid(*this).name() << std::endl;
}

int main()
{
    DEBUG_INSTANCE(Foo, a);
    DEBUG_INSTANCE(Foo, b);

    a.Print();
    b.Print();

    system("PAUSE");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Instance name = ?AV_Foo_INSTANCE_a_@?1?main@
Instance name = ?AV_Foo_INSTANCE_b_@?1?main@
Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)

该宏将创建一个继承Foo的类,name包含实例名称.唯一的限制是Foo有一个默认构造函数,并且必须包含一个虚方法,以便typeid接受继承的类并在运行时调用.有关更好的说明,请参阅/sf/answers/472299131/

如果使用__VA_ARGS__宏,可能支持构造函数


小智 5

实例当然可以从类方法中知道其名称:

#include <iostream>

class Foo {
  public:
    void Print() { std::cout << "Instance name = " << this << std::endl; }
};

int main() {
    Foo a, b;
    a.Print();
    b.Print();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

将产生类似于此的输出:

Instance name = 0x7fff502b8b48
Instance name = 0x7fff502b8b40
Run Code Online (Sandbox Code Playgroud)

至于知道变量名,肯定是不可能的.对象的存在并不意味着存在变量 - 这个实例:

new Foo();
Run Code Online (Sandbox Code Playgroud)

将在剩余的过程中存在,但永远不会与任何变量相关联.变量的语言概念没有反映在所述变量的内容中,并且语言变量和对象之间的任何潜在关系仅在生成的代码中表示,而不在生成的数据或元数据中表示.当然,除非已经指出,否则访问调试信息不​​是语言的一部分.