扩展c++中的thrift生成对象
Extending a thrift generated object in C++
使用以下.thrift
文件
struct myElement {
1: required i32 num,
}
struct stuff {
1: optional map<i32,myElement> mymap,
}
我得到一个带有STL映射的节俭生成的类。该类的实例是长期存在的(我添加并删除它,并使用TSimpleFileTransport将其写入磁盘)。
我想在c++中扩展myElement
,扩展应该不会影响此对象的序列化版本(此对象没有在任何其他语言)。有什么干净的方法可以做到这一点?
我考虑了以下内容,但它们似乎并不清晰:
- 创建第二个非节俭映射,使用相同的键索引
- 保持两者同步可能是一种痛苦
- 通过对生成的代码进行后处理来修改生成的代码头文件(包括proprocessor hackery).
- 与#2类似,但修改生成端,在生成的结构体中包含以下内容,然后在强制包含的头文件中定义NAME_CXX_EXT
#ifdef NAME_CXX_EXT NAME_CXX_EXT ... #endif
以上这些看起来都很讨厌
我现在要使用的解决方案:
[这都是伪代码,没有检查编译副本]
下面生成的代码,我无法修改(虽然我可以将映射更改为set)
class GeneratedElement {
public:
// ...
int32_t num;
// ...
};
class GeneratedMap {
public:
// ...
std::map<int32_t, GeneratedElement> myGeneratedMap;
// ...
};
// End of generated code
应用别处:
class Element {
public:
GeneratedElement* pGenerated; // <<== ptr into element of another std::map!
time_t lastAccessTime;
};
class MapWrapper {
private:
GeneratedMap theGenerated;
public:
// ...
std::map<int32_t, Element> myMap;
// ...
void doStuffWIthBoth(int32_t key)
{
// instead of
// theGenerated.myGeneratedMap[key].num++; [lookup in map #1]
// time(&myMap[key].lastAccessTime); [lookup in map #2]
Element& el=myMap[key];
el.pGenerated->num++;
time(&el.lastAccessTime);
}
};
我想避免每次访问都使用double map查找(虽然我知道复杂度保持不变,但它仍然是两次查找)。
我想我可以保证所有插入和删除到/从theGenerated
)是在一个地方完成的,在同一个地方是我填充/删除在myMap
中对应的条目,然后我就可以初始化了元素::pGenerated到生成的mygeneratedmap中对应的元素
这不仅可以让我节省一半的查找时间,我甚至可以改变为我的键类型(例如hash_map或甚至boost)提供更好的容器类型多索引地图)
一开始我觉得这是个坏主意。使用std::vector和std::dqueue,我可以看看这是如何成为一个问题的,因为这些值会被移动,使指针失效。假设std::map是用树来实现的结构,是否真的存在一个映射元素将被重新定位的时间?(我的上述假设在这里输入链接描述的讨论中得到了证实)
虽然我可能不会为myElement
的每个成员提供访问方法或任何语法糖(如重载[]()等),但这使我能够以几乎一致的方式处理这些元素。唯一的关键是(除了插入)我从不直接查找mymap
的成员。
你考虑过使用简单的集装箱吗?
您正在使用c++,因此您可以将结构体包装在一些类或其他结构体中,并提供包装方法来做任何您想做的事情。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 构造对象的歧义
- 扩展c++中的thrift生成对象