对于C ++中的协议缓冲区,我想知道在类中包含protobuf消息还是从外部protobuf消息构造并填充该消息是更好的选择。
我找不到描述此案例最佳实践的示例。我特别担心两种设计之间的性能差异。
在我的处理过程中,有些情况下,我将只读取消息中的几个字段,然后将其路由到另一个进程(可能在将消息发送回sendind之前对其进行处理),而另一些情况下,我的对象将具有使用寿命长,可多次使用,然后再次序列化。在第一种情况下,我可能直接在protobuf消息上操作,甚至不需要我的类,execpt来适应现有接口。
这是一个示例消息:
package example;
message Example {
optional string name = 1;
optional uint32 source = 2;
optional uint32 destination = 3;
optional uint32 value_1 = 4;
optional uint32 value_2 = 5;
optional uint32 value_3 = 6;
}
我可以在课堂上看到以下设计之一。我知道这些类除了访问数据外没有做任何其他事情,但这不是我要针对此问题重点关注的内容。
作品
class Widget
{
public:
Widget() : message_() {}
Widget(const example::Example& other_message)
: message_(other_message) {}
const example::Example& getMessage() const
{ return message_; }
void populateMessage(example::Example& message) const
{ message = message_; }
// Some example inspectors filled out...
std::string getName() const
{ return message_.name(); }
uint32_t getSource() const;
{ return message_.source(); }
uint32_t getDestination() const;
uint32_t getValue1() const;
uint32_t getValue2() const;
uint32_t getValue3() const;
// Some example mutators filled out...
void setName(const std::string& new_name)
{ message_.set_name(new_name); }
void setSource(uint32_t new_source);
{ message_.set_source(new_source); }
void setDestination(uint32_t new_destination);
void setValue1(uint32_t new_value);
void setValue2(uint32_t new_value);
void setValue3(uint32_t new_value);
private:
example::Example message_;
};
标准数据成员
class Widget
{
public:
Widget();
Widget(const example::Example& other_message)
: name_(other_message.name()),
source_(other_message.source()),
destination_(other_message.destination()),
value_1_(other_messsage.value_1()),
value_2_(other_messsage.value_2()),
value_3_(other_messsage.value_3())
{}
example::Example getMessage() const
{
example::Example message;
populateMessage(message);
return message;
}
void populateMessage(example::Example& message) const
{
message.set_name(name_);
message.set_source(source_);
message.set_value_1(value_1_);
message.set_value_2(value_2_);
message.set_value_3(value_3_);
}
// Some example inspectors filled out...
std::string getName() const
{ return name_; }
uint32_t getSource() const;
{ return source_; }
uint32_t getDestination() const;
uint32_t getValue1() const;
uint32_t getValue2() const;
uint32_t getValue3() const;
// Some example mutators filled out...
void setName(const std::string& new_name)
{ name_ = new_name; }
void setSource(uint32_t new_source);
{ source_ = new_source; }
void setDestination(uint32_t new_destination);
void setValue1(uint32_t new_value);
void setValue2(uint32_t new_value);
void setValue3(uint32_t new_value);
private:
std::string name_;
uint32_t source_;
uint32_t destination_;
uint32_t value_1_;
uint32_t value_2_;
uint32_t value_3_;
};
这里没有公认的“最佳实践”。我已经看到了很多两者的示例,甚至看到了可以双向工作的程序。有人对此有非常强烈的意见,但我认为这取决于用例。例如,正如您所说,如果您打算将大多数数据转发到另一台服务器,那么保留protobuf对象就很有意义了。但是有时您会拥有更方便的内部表示形式-例如,在protobufs添加对地图的本机支持之前,如果您有一个protobuf将地图表示为键/值对的重复列表,则可能需要将其转换为std::map
前期。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句