答案 0 :(得分:10)
这里的作文最合适:
struct Msg1
{
HDR hdr;
char text[20];
};
虽然你可以使用C ++继承,但在这种情况下它在语义上并没有意义。 Msg1
不是HDR
。
或者(可能优先),您可以定义一个抽象的Msg
基类型:
struct Msg
{
HDR hdr;
protected:
Msg() {}
};
并从中获得所有具体的消息类。
答案 1 :(得分:8)
正常的C ++继承有什么问题?
struct HDR { ... };
struct Msg1: HDR { ... };
只是不要声明任何虚拟成员函数,你就可以全部设置。
答案 2 :(得分:2)
答案 3 :(得分:1)
处理二进制网络协议的常见模式是定义包含union的结构:
struct Message {
Header hdr;
union {
Body1 msg1;
Body2 msg2;
Body3 msg3;
};
};
在语义上,您声明Message
由Header
和一个Body1
,Body2
中的一个组成......现在,提供插入和标题和每个主体的提取操作符分开。然后通过Message
上的Header
调用它来实现Message
的相同运算符,并根据消息类型,有意义的消息正文。
请注意,union的元素不需要具有相同的大小。联合的大小将是其成员大小的最大值。该方法允许可以从网络读取/写入的紧凑二进制表示。您的读/写缓冲区将是// Define operators:
std::ostream& operator<<( std::ostream&, Header const & );
std::ostream& operator<<( std::ostream&, Body1 const & ); // and the rest
// Message operator in terms of the others
std::ostream& opeartor<<( std::ostream& o, Message const & m )
{
o << m.header;
switch ( m.header.type ) {
case TYPE1: o << m.body1; break;
//...
};
return o;
}
// read and dump the contents to stdout
Message message;
read( socket, &message, sizeof message.header ); // swap the endianness, check size...
read( socket &message.msg1, message.header.size ); // ...
std::cout << message << std::endl;
,您将只读取标题,然后读取相应的正文。
{{1}}