未定义对“ <class>的typeinfo”的引用

时间:2019-06-11 06:47:57

标签: c++ linux

我看到了有关此问题的问题,但找不到适合我的解决方案。我在C ++中使用Visual Code,而C ++版本早于C ++ 11。 我有DNS类,各种类继承了主要的DNS消息类,这样我就可以分解一些属性。在类型类型字段的功能中,我可以知道对象的类型。 例如,当我进行编译时,出现错误“对“针对DNS_RR_A的typeinfo的未定义引用””,但是我在每次动态强制转换时都得到了此信息,以检查对象的类。

我的dnsMessage.cpp只有构造函数和析构函数。

这是我的课程:

class CDnsMessage
{       
    public:
        CDnsMessage();
        virtual ~CDnsMessage();

        virtual void GetSize() = 0;

        uint32_t       m_ttl;
        eDnsClass      m_class;
        eDnsType       m_type; 
        std::string    m_domain; 
        uint8_t        m_sizeDnsCorpse;
        uint8_t        m_sizeDomainName; 
};

class CDns_RR_A : public CDnsMessage
{
    public:
        CDns_RR_A();
        virtual ~CDns_RR_A();

        virtual void GetSize() {/*....*/}

        uint32_t        m_address;
};

这是我的函数示例,在动态转换时使用了错误。我收到了我必须编码的消息,但我不知道消息的性质,因此我进行了动态投射,因此可以调整编码:

//i receive a message i have to encode, i don't know the type 
void EncodeOpaqueData(CDnsMessage & msg, std::vector<uint8_t>& output)
{
//where i encode
    output.clear();

    // Error : "undefined reference to `typeinfo for CDns_RR_A'"
    if(dynamic_cast< CDns_RR_A* >( &msg ) != NULL) 
    {       
            CDns_RR_A* RR_A_msg = dynamic_cast< CDns_RR_A* >( &msg );

            uint16_t dnstype = cmn_hton16(1);
            output.push_back(dnstype);
            output.push_back(dnstype >> 8);
            /* stuff here */

            uint32_t address = cmn_hton32(RR_A_msg->m_address);
            for (int i = 0; i < 4; i++)
            {
                    output.push_back(static_cast<uint8_t>(address >>(i * 8)));
            }

    }
}

在考虑了更多函数之后,除了检查对象的类型,我可以检查msg-> m_type并适应该类型的函数,例如,可以错误地实例化m_type变量。但是无论如何,我想了解这个错误以及如何解决。 预先感谢。

2 个答案:

答案 0 :(得分:2)

尝试将引用参数更改为这样的指针:

void EncodeOpaqueData(CDnsMessage * msg, std::vector<uint8_t>& output)

您在这里有解释:

Difference in behavior while using dynamic_cast with reference and pointers

答案 1 :(得分:2)

编译第一个声明的虚拟方法时,将生成类impedimenta(虚拟方法表和typeinfo)。您是定义 virtual ~CDnsMessage();(即CDnsMessage::~CDnsMessage() {}),并且是包含在链接中的文件吗?

请注意,离线定义并不弱,因此必须在一个源文件(而不是头文件)中进行定义。