C++ Protobuf add创建对象的disks成员地址重复问题咨询
问题产生原因
- Protobuf 中用
optional修饰的复合消息类型字段,默认的字段名()Getter 方法返回的是全局单例的默认不可变实例。你没有主动给disks字段赋值的前提下,所有未初始化的optional Disks字段都会返回同一个默认实例的常量引用,所以取到的地址自然完全相同。 - 你感知到的"修改一个IpInfo的disks,所有IpInfo的disks都同步修改"是错误测试导致的错觉:这个默认实例本身是只读的,正常调用修改接口只会触发写时复制逻辑,仅修改当前操作的对象对应的字段,不会影响其他实例。
解决方法
如果需要给每个IpInfo配置独立的disks内容,使用Protobuf提供的mutable_字段名()方法获取当前对象专属的disks实例指针即可:
GetIdKeyValueResp resp; for (int i = 0; i < 10; i++) { IpInfo* ipinfo = resp.add_ips(); // 调用mutable_disks主动为当前IpInfo分配独立的disks内存空间 Disks* disks = ipinfo->mutable_disks(); cout << disks << endl; // 后续直接操作disks指针修改内容,不同IpInfo的disks完全独立互不影响 }
运行以上代码后输出的10个地址会完全不同,不会再出现修改互相干扰的问题。
注意事项
- 只有主动调用
mutable_xxx()、set_allocated_xxx()接口给optional复合字段赋值后,该字段才会分配专属的内存空间,否则都会指向全局默认只读实例。 - 禁止对
disks()返回的常量引用强制转型后修改,会触发未定义行为。
内容的提问来源于stack exchange,提问作者q57259028
相关产品推荐
相关产品推荐

