protobuf: 通讯录2.2
1.proto3
4.Any
其实也是一个.proto文件中的message类型(protobuf内置的)。
用的时候需要导入:
作用:可以存储任意消息类型,类似于面向对象编程中的多态
生成的Any字段方法:
public:
// .google.protobuf.Any data = 4;
bool has_data() const;
private:
bool _internal_has_data() const;
public:
void clear_data();
const ::PROTOBUF_NAMESPACE_ID::Any& data() const;
PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Any* release_data();
::PROTOBUF_NAMESPACE_ID::Any* mutable_data();
void set_allocated_data(::PROTOBUF_NAMESPACE_ID::Any* data);
解释:
has_data() 方法:判断当前data是否已经被赋值
mutable_data()方法:得到返回值为Any类型的指针,这类⽅法会为我们开辟好空间,可以直接对这块空间的内容进⾏修改。
库中的Any字段本身方法:
class PROTOBUF_EXPORT Any final : public ::PROTOBUF_NAMESPACE_ID::Message {
bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) {
...
}
bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const {
...
}
template<typename T> bool Is() const {
return _impl_._any_metadata_.Is<T>();
}
};
解释:
PackFrom() ⽅法可以将任意消息类型转为 Any 类型。
UnpackTo() ⽅法可以将 Any 类型转回之前设置的任意消息类型。
Is() ⽅法可以⽤来判断存放的消息类型是否为 typename T。
2.通讯录2.2:用Any字段接收下面的Address地址类型
contacts.proto
message Address
{
string home_addr = 1;
string unit_addr = 2;
}
message People
{
string name = 1;
int32 age = 2;
//里面是电话的字段和类型
message Phone
{
string num = 1;
enum PhoneType
{
MP = 0; // 移动电话
TEL = 1; // 固定电话
}
PhoneType type = 2;
}
//repeated 表示重复 相当于定义一个数组 里面全是Phone
repeated Phone phone = 3;
google.protobuf.Any data = 4;
write.cc(只展示新增部分)
contacts::Address address;
std::string home_add;
std::cout << "请输入联系人的家庭住址: ";
getline(std::cin, home_add);
address.set_home_addr(home_add);
std::string unit_add;
std::cout << "请输入联系人的单位住址: ";
getline(std::cin, unit_add);
address.set_unit_addr(unit_add);
google::protobuf::Any *any = person->mutable_data();
// address->Any
any->PackFrom(address);
read.cc(只展示新增部分)
//has_data: 判断any对象是不是一个已经被赋值的数据 data():返回any对象,Is(): 模板函数,判断是否有这个类型
if(person.has_data() && person.data().Is<contacts::Address>())
{
contacts::Address address;
person.data().UnpackTo(&address);
if(!address.home_addr().empty())
std::cout << "联系人家庭住址: " << address.home_addr() << std::endl;
if(!address.unit_addr().empty())
std::cout << "联系人单位住址: " << address.unit_addr() << std::endl;
}