【问题标题】:can't access my inherited class attributes无法访问我继承的类属性
【发布时间】:2019-10-21 15:42:36
【问题描述】:

我正在为我的工作开发一个项目,以在 C++ 中将 DNS 记录对象编码/解码到缓冲区中。有些记录有相同的信息,所以我用这些基本信息创建了一个类 Dns 消息:

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

    virtual int GetSize() = 0;
    uint32_t       m_ttl; 
    DnsClass       dclass; 
    DnsType        type; 
    std::string    m_domain;    
};

DnsClassDnsTypes 是我使用的不同类/类型的枚举。然后我有我的每条记录的子类,我将以 A 为例:

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

    virtual ~CDns_RR_A();
    virtual int GetSize(CDnsMessage const& msg);

    uint32_t        m_address;
};

然后我在另一个标头encoder.hencoder.cpp 中有我的编码/解码功能。

我正在接收DnsMessage(对象)和接收缓冲区,然后我进行编码或解码。所以我使用动态转换来知道它是哪种类型的记录,并将编码和解码适应对象具有的变量。 这是我的解码示例:

EncodeResult DecodeData(const char * buffer,CDnsMessage & msg,std::size_t size)
{
    EncodeResult res(ENCODE_OK);

    uint32 ttl = 0;
    eDnsClass dnsclass;
    eDnsType  dnstype;

    //decoding RR_A
    if(CDns_RR_A* RR_A_msg = dynamic_cast< CDns_RR_A* >( &msg ))
    {       
        uint32_t address;

        dnsclass = CLASS_IN;
        msg.dclass = dnsclass;
        dnstype = TYPE_A;
        msg.type = dnstype;

        res = DecodeInt32(&buffer,&size,&ttl);
        CHECK_DECODE_ERROR(res);
        msg.m_ttl = ttl;

        res = DecodeInt32(&buffer,&size,&address);
        CHECK_DECODE_ERROR(res);
        msg.m_address = address;
    }
}

DecodeInt32是很久以前人们做的一个函数,它需要一个缓冲区(char**),一个size_t*和一个uint32

我有两个问题,首先我无法访问我的子类的成员,当我编译时我遇到了 msg.dclass 或 msg.type 的问题,它说“在 'RR_A_msg' 中请求成员 'class',属于非类类型“CDns_RR_A*” 但我不明白,如果我的动态演员表有效,是否意味着收到的等待完成的味精是 A 类型的不?

我的第二个问题是:我使用 uint32_t 作为 ttl(由企业强加),而我的 decodeint32 使用 uint32,所以编译器会显示 invalid conversion from uint32_t* to uint32

是否可以将一个转换为另一个?

编辑: 根据答案和建议更新了我的代码,现在我有了

if(dynamic_cast< CDns_RR_A* >( &msg ) != nullptr)
                            {       
                                    CDns_RR_A* RR_A_msg = dynamic_cast< CDns_RR_A* >( &msg )

                                    uint32 address;

                                    dnsclass = CLASS_IN;
                                    RR_A_msg->dclass = dnsclass;
                                    dnstype = TYPE_A;
                                    RR_A_msg->type = dnstype;

                                    res = DecodeInt32(&buffer,&size,&ttl);
                                    CHECK_DECODE_ERROR(res);
                                    RR_A_msg->m_ttl = ttl;

                                    res = DecodeInt32(&buffer,&size,&address);
                                    CHECK_DECODE_ERROR(res);
                                    RR_A_msg->m_address = address;
                            }

将 uint32_t 更改为 uint32 以进行解码,并且使用 RR_A_msg-> 代替 msg。也工作了。 但现在我有undefined reference totypeinfo 用于 CDns_RR_A'`

【问题讨论】:

  • if(CDns_RR_A* RR_A_msg = dynamic_cast&lt; CDns_RR_A* &gt;( &amp;msg )) 看起来不寻常。只需写if(dynamic_cast&lt; CDns_RR_A* &gt;( &amp;msg ) != nullptr)
  • 感谢您的建议,我刚刚改变了。但要执行“RR_A_msg->m_address”,我仍然必须按照我执行 RR_A_ 的方式进行初始化
  • RR_A_msg 未在代码中使用。你不需要一个临时的。

标签: c++ linux dns


【解决方案1】:

对于“您无法将 uint32_t* 转换为 uint32”的问题是前者是指针,而后者不是。你应该把 & 从前面去掉,传递值而不是指向它的指针。

我不知道为什么你不能获取类成员(可能与使用保留名称作为变量有关?)但你不应该能够以这种方式访问​​ m_address。

代替

msg.m_address

你需要使用

RR_A_msg->m_address

【讨论】:

  • 谢谢,刚刚使用它,它非常适合 uint。对于 msg.m_address,我使用了您的解决方案(我的错误更少),但我现在有了这个:“未定义对 `typeinfo for CDns_RR_A' 的引用”
  • 这篇文章有一些可能的解决方案:*.com/questions/307352/…。可能您需要在 CDns_RR_A 中的虚函数上使用覆盖说明符
  • 是getSize在派生类上的函数签名。它需要与底座上的相同。您也不需要传入基类的实例,因为基类的成员在派生类中可用
  • 但是当我调用我的函数时,我不知道我是否有 A 记录对象或 SRV,所以我必须传递一个通用对象:CDnsMessage 否?
  • 我尝试在 .h 和 .cpp 中注释 Getsize 以查看这是否消除了错误但仍然无法编译。