从DLL调用时,typeid不返回派生类

时间:2015-02-03 09:23:34

标签: c++ templates dll polymorphism typeid

我正在使用typeid为我的应用程序生成调试输出。我依赖于typeid对基类的解引用指针的多态行为。

现在我遇到了一个问题,即编译器错误或一些奇怪的类型推导规则一见不鲜。

我有一个公共基类,它采用模板参数,该参数在公共头文件中定义:

class Type {};
template<typename T>  class Base { virtual void dummy() {} };

然后我有两个DLL:

  • 包含派生类Base<Type>及其实例的一个。

    #include "commonheader.h"
    
    class Derived : public Base<Type> { };
    Derived instance;
    main() { CallDLL(&instance); }
    
  • 和另一个具有使用指向Base<Type>的指针的函数。使用第一个DLL中的实例地址调用此函数。

    #include "commonheader.h"
    
    void CallDLL(Base<Type>* b_ptr)
    {
        std::string typeName1 = typeid(*b_ptr).name();
        std::string typeName2 = typeid(*&*b_ptr).name();
    }
    

据我所知typeName1应评估为"class Derived",因为*b_ptr它是一个指向多态基类的解引用指针。但事实并非如此。结果是"class Base<class Type>"。 最令人惊讶的是,当添加另一层间接时,typeName2确实是"class Derived"

所以这里的主要问题是typeid(*b_ptr) != typeid(*&*b_ptr),这应该永远不会发生。

如您所见,第二个版本解决了我为b_ptr指向的派生类最多的调试输出名称的原始问题。但我无法解释为什么,我想知道这是否是预期的行为。

进一步评论:

  • 我正在使用Visual Studio 2010.我还没有测试过另一个编译器。
  • 无法进一步简化问题:
    • Derived的定义放在标题中会产生正确的输出。
    • 将所有内容放在一个DLL(或EXE)中会产生正确的输出。
    • Base中删除模板参数会产生正确的输出。

感谢您的帮助!

0 个答案:

没有答案