-1

win32 调试器在检查器窗口中显示有问题的类名,这意味着信息必须可用,只有微软开发人员公开该功能才有问题。

出于调试/诊断/开发目的,我想编写一个函数来获取 c++ 对象的实例化类名作为输出,并将指向基类的指针作为输入。

例如:

const char* GetNameOfInstanciatedClassByBaseClassPtr(class B* pBaseClassOrInstanciatedClass);

class B { public: virtual void Init (){
  assert(StringIsEqual(GetNameOfInstanciatedClassByBaseClassPtr(this), "C")); } };
class C : B {} c; c.Init(); 

因此,请提供实现函数GetNameOfInstanciatedClassByBaseClassPtr的解决方案。

所以问题是:需要什么 lib/header/function ?我想一个用于 win32 调试信息的 API 会有所帮助吗?

在我的情况下,编写返回字符串或 type_info 的虚拟函数不是可接受的解决方案。

正如我之前所说:这仅用于诊断/调试/开发目的,不适用于生产代码,因此请避免讨论干净代码的目的。我也可以手动收集信息,但因为它大约有 260 个课程,所以我可能会更快。;)

编辑:在问题的第一个版本中,我在基类的构造函数中调用了函数“GetNameOfInstanciatedClassByBaseClassPtr”,但我观察到该信息在构造函数时尚不可用。所以我把它放在一个总是被调用的 Init 方法中。在此方法中,调试器显示实例化类的名称,因此如果我将对函数 GetNameOfInstanciatedClassByBaseClassPtr 的调用放入我的 init 方法中,则可以获得信息。rtti-typeinfo 似乎也是如此。

EDIT2:如前所述,它可能不适用于 void*,您可能需要 B* 类。但是,这很容易测试。请注意,有些事情可能是编译器特定的。所以我再次调整了这个问题。

所以我从评论中得到的答案是使用

  • 运行时类型信息 (rtti)(通过本机 c++) [1]
  • Microsoft 调试接口访问 SDK(通过 COM) [2]

[1] 您需要在文件或项目的编译器设置中启用此功能。

[2] 这是更复杂的解决方案。

4

1 回答 1

0

您可以使用typeid

#include <iostream>
#include <typeinfo>

struct A {
    virtual void printName(){
        std::cout << typeid(*this).name() << "\n";
    }
    virtual ~A() = default;
};
struct C : A{};

int main() {
    C c;
    c.printName();
    A a;
    a.printName();
}

但是,名称是实现定义的。可能的输出是

1C
1A

并且您无法typeidvoid*. 看到这个有点相关的问题:How to get the typeid of a void* pointer?

另外(来自cppreference

如果typeid用于正在构造或销毁的对象(在析构函数或构造函数中,包括构造函数的初始化列表或默认成员初始化程序),则此 typeid 引用的 std::type_info 对象表示正在构造或销毁的类即使它不是派生最多的类。

也就是说,您不能使用typeid来推断构造函数(或析构函数)中的动态类型。我知道在构造函数或析构函数中获取动态类型的唯一方法是 a dynamic_cast,但是你需要事先知道类型。

于 2021-07-29T08:11:27.053 回答