C++中抽象类vector的实现优化问询(SQL数据库场景)
Tuple类字段存储与读写的优化方案
针对你用std::vector<std::shared_ptr<Field>>实现Tuple字段存储的场景,以下是几个实用的优化方向:
改用
std::unique_ptr<Field>替代std::shared_ptr<Field>
Tuple作为字段的唯一持有者,完全不需要共享所有权,unique_ptr比shared_ptr更轻量,省去了引用计数维护的额外开销。示例代码:class Tuple { private: std::vector<std::unique_ptr<Field>> fields; public: Field* GetField(size_t idx) { return fields[idx].get(); } const Field* GetField(size_t idx) const { return fields[idx].get(); } void SetField(size_t idx, std::unique_ptr<Field> field) { fields[idx] = std::move(field); } void AddField(std::unique_ptr<Field> field) { fields.emplace_back(std::move(field)); } };预分配容器空间
如果Tuple对应的表结构字段数量固定,在构造Tuple时直接调用reserve预分配足够空间,避免vector动态扩容时的内存拷贝开销:Tuple::Tuple(size_t field_count) { fields.reserve(field_count); // 可按需初始化空指针或直接构造对应字段实例 for (size_t i = 0; i < field_count; ++i) { fields.emplace_back(nullptr); } }类型安全的模板化访问方法
提供模板版的字段获取方法,避免运行时dynamic_cast的开销,同时在编译期保证类型正确性:template<typename FieldType> FieldType* GetTypedField(size_t idx) { return static_cast<FieldType*>(fields[idx].get()); } template<typename FieldType> const FieldType* GetTypedField(size_t idx) const { return static_cast<const FieldType*>(fields[idx].get()); } // 使用示例 auto int_field = tuple.GetTypedField<IntField>(0); if (int_field) { int value = int_field->GetValue(); }调试阶段可加入断言确保类型匹配:
#ifdef NDEBUG assert(dynamic_cast<FieldType*>(fields[idx].get()) != nullptr); #endif固定字段类型场景下用
std::variant替代多态指针
如果你的Field派生类只有固定几种(比如仅IntField、StringField),可以用std::variant存储字段,彻底消除堆分配和指针间接访问的开销:class Tuple { private: std::vector<std::variant<IntField, StringField>> fields; public: template<typename Visitor> auto VisitField(size_t idx, Visitor&& visitor) { return std::visit(std::forward<Visitor>(visitor), fields[idx]); } void SetField(size_t idx, IntField field) { fields[idx] = std::move(field); } void SetField(size_t idx, StringField field) { fields[idx] = std::move(field); } }; // 使用示例 tuple.VisitField(0, [](auto& field) { using T = std::decay_t<decltype(field)>; if constexpr (std::is_same_v<T, IntField>) { std::cout << field.GetValue() << std::endl; } else if constexpr (std::is_same_v<T, StringField>) { std::cout << field.GetValue() << std::endl; } });注意:此方案会失去多态扩展性,新增Field类型时需要修改variant定义。
暴露迭代器支持批量操作
如果需要批量处理字段,可提供方法返回容器迭代器,减少多次调用GetField的开销:auto begin() { return fields.begin(); } auto end() { return fields.end(); } auto begin() const { return fields.begin(); } auto end() const { return fields.end(); } // 使用示例 for (auto& field_ptr : tuple) { field_ptr->DoSomething(); }
内容的提问来源于stack exchange,提问作者Franciszek Malinka
相关产品推荐
相关产品推荐

