Most C++ developers intuitively choose to express every independent message as a separate class, which inherit from a common interface.
class Message
{
public:
void write(...) const {
writeImpl(...);
}
...
protected:
// Implements writing to a buffer functionality
virtual void writeImpl(...) const = 0;
};
class ActualMessage1 : public Message
{
...
protected:
virtual void writeImpl(...) const override {...};
};
class ActualMessage2 : public Message
{
...
protected:
virtual void writeImpl(...) const override {...};
};
// Send any message
void sendMessage(const Message& msg)
{
...
msg.write(...); // write message to a buffer
...// send buffer contents over I/O link;
}