双向关联类生成ODB文件失败问题求助
ODB双向关联编译错误解决方案
错误原因
ODB无法直接映射std::weak_ptr<T>到数据库类型,因为ODB的对象关联机制依赖**可追踪的强引用(std::shared_ptr)**来维护外键关系,weak_ptr作为弱引用不持有对象所有权,无法被ODB用于持久化关联逻辑。
具体修复步骤
1. 替换集合中的weak_ptr为shared_ptr
在chat.hxx中,将关联集合的类型从weak_ptr改为shared_ptr,让ODB能识别并维护数据库外键:
// 原代码 std::vector<std::weak_ptr<message>> m_messages; std::vector<std::weak_ptr<user>> m_members; // 修改后 std::vector<std::shared_ptr<message>> m_messages; std::vector<std::shared_ptr<user>> m_members;
2. 修正头文件循环依赖与语法错误
message.hxx中不要直接包含chat.hxx,改用前向声明class chat;,避免循环包含问题:// 移除 #include "./chat.hxx" class chat; // 添加前向声明- 删除
chat.hxx末尾多余的#pragma db object(chat)和额外的};,这属于无效语法:// 移除以下两行 #pragma db object(chat) };
3. 确保双向关联配置正确
保持chat.hxx中inverse指令对应message类的关联成员名(m_chat),双向关联的配置即可正常生效。
修改后的完整代码
chat.hxx
#include "./root_model_object.hxx" #include <memory> #include <string> #include <vector> class message; class user; /** * @brief class of chat object in model * */ #pragma db object pointer(std::shared_ptr) class chat final : public root_model_object { private: friend class odb::access; std::string m_name; #pragma db value_not_null inverse(m_chat) std::vector<std::shared_ptr<message>> m_messages; #pragma db value_not_null inverse(m_chats) std::vector<std::shared_ptr<user>> m_members; public: chat() = default; void setName(const std::string &name) { m_name = name; }; const std::string &getName() const { return m_name; }; void setMessages(const std::vector<std::shared_ptr<message>> &messages) { m_messages = messages; }; const std::vector<std::shared_ptr<message>> &getMessages() const { return m_messages; }; void setMembers(const std::vector<std::shared_ptr<user>> &members) { m_members = members; }; const std::vector<std::shared_ptr<user>> &getMembers() const { return m_members; }; };
message.hxx
#include "./root_model_object.hxx" #include "./user.hxx" #include <ctime> #include <memory> #include <string> class chat; // 前向声明替代头文件包含 /** * @brief class of message object in model * */ #pragma db object pointer(std::shared_ptr) class message final : public root_model_object { private: friend class odb::access; std::string m_content; #pragma db not_null std::shared_ptr<user> m_sender; std::time_t m_send_date; #pragma db not_null std::shared_ptr<chat> m_chat; public: message() = default; void setContent(const std::string &content) { m_content = content; }; const std::string &getContent() const { return m_content; }; void setSender(const std::shared_ptr<user> &sender) { m_sender = sender; }; const std::shared_ptr<user> &getSender() const { return m_sender; }; void setSendDate(const std::time_t &send_date) { m_send_date = send_date; }; const std::time_t &getSendDate() const { return m_send_date; }; void setChat(const std::shared_ptr<chat> &chat) { m_chat = chat; }; const std::shared_ptr<chat> &getChat() const { return m_chat; }; }; #pragma db object(message)
额外说明
如果业务逻辑中需要避免循环引用导致的内存泄漏,可以在类中单独维护weak_ptr的视图(仅用于业务代码),但ODB持久化必须依赖shared_ptr的关联集合。
内容的提问来源于stack exchange,提问作者MGuillaumeF
相关产品推荐
相关产品推荐

