在C ++中重写方法

时间:2014-04-19 18:25:56

标签: c++ polymorphism

我已经定义了一个基类Message,它有几个代表特定消息类型的派生类。每种消息类型都具有关联的序列化和反序列化功能。基类有一个字段' type'而子类包含消息特定字段。

class Message
{
public:

    int seq;
    Message();
    ~Message();

    char getType();
    void setType(char);
    virtual void deserializeMsg(const char [256], Message&);
    virtual void serializeMsg(Message&, std :: vector<char>);

private:
    char type;
};

class DataMsg : public Message
{
public:
    string data;
    DataMsg();
    ~DataMsg();
    void serializeMsg(DataMsg&, std :: vector<char>);
    void deserializeMsg(const char [256], DataMsg&);
};

方法如下:

void DataMsg :: serializeMsg(DataMsg &m, std :: vector<char> out)
{
    char type = m.getType();
    char temp [256];
    uint16_t seq = htons(m.seq);
    memcpy(temp, &type, sizeof(type));
    memcpy(temp + sizeof(type), &seq, sizeof(seq));
    memcpy(temp + sizeof(seq) + sizeof(type), m.data.c_str(), m.data.length());
    out.assign(temp, temp + sizeof(seq) + sizeof(type) + m.data.length());
}

void DataMsg :: deserializeMsg(const char out[256], DataMsg& m)
{
    char type = m.getType();
    memcpy(&type, out, sizeof(type));
    out += sizeof(type);
    uint16_t seq;
    memcpy(&seq, out, sizeof(seq));
    m.seq = ntohs(seq);

}

我在main中声明指向Message的指针,并根据接收到的消息的类型字段将其分配给其中一个子类。

int main()
{
    char* buf;
    buf = "D0001";
    Message* a;
    if(buf[0] == 'D')
    {
        a = new DataMsg;
        a -> deserializeMsg(buf, *a);
    }
    return 0;
}

但是,我无法弄清楚如何覆盖serializeMsg和deserializeMsg方法。使用虚拟不起作用,因为方法的签名是不同的。如果我签名相同,我就无法通过基类引用访问子类字段。 我可以通过基类引用访问子类成员吗?或者有更好的方法来实现这个吗?

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

我认为你不需要deserializeMsg中的第二个参数。

将基类中的签名更改为:

virtual void deserializeMsg(const char [256]);

DataMsg中的实施更改为仅使用this而不是第二个参数。

void DataMsg :: deserializeMsg(const char out[256])
{
    char type = this->getType(); // Not sure why you need this.
                                 // You are overriding its value in the next line.
    memcpy(&type, out, sizeof(type));
    out += sizeof(type);
    uint16_t seq;
    memcpy(&seq, out, sizeof(seq));
    this->seq = ntohs(seq);    
}

您可以对serializeMsg的签名及其在DataMsg中的实施进行类似的更改。

virtual void serializeMsg(std :: vector<char>& out);
// Without using `std::vector<char>&`, any changes you make in 
// the function to out are only local changes. The changes won't
// be visible to the calling function.


void DataMsg :: serializeMsg(std :: vector<char>& out)
{
    char type = this->getType();
    char temp [256];
    uint16_t seq = htons(this->seq);
    memcpy(temp, &type, sizeof(type));
    memcpy(temp + sizeof(type), &seq, sizeof(seq));
    memcpy(temp + sizeof(seq) + sizeof(type), this->data.c_str(), this->data.length());
    out.assign(temp, temp + sizeof(seq) + sizeof(type) + this->data.length());
}

答案 1 :(得分:1)

好的,你应该这样做:

virtual void deserializeMsg(const char [256], Message*);
virtual void serializeMsg(Message*, std :: vector<char>);

然后在派生类中:

void DataMsg :: serializeMsg(Message *m, std :: vector<char> out)
{
    DataMsg* msg = (DataMsg*)m;
}

正如我之前所说,如果你使用指针,你可以将基类指针转换为派生类,使用相同的签名但传递你喜欢的数据......