哪些容器存储通过不同标识符访问的对象
Which containers to store objects for access via different identifiers?
我必须通过几个不同的标识符访问我的对象(来自一个类的多个实例),并且不知道存储从标识符到对象的映射的最佳方法是什么。我充当两个世界之间的"连接器",每个世界都有自己的标识符,我必须使用/支持。如果可能的话,我希望避免使用指针。
第一个想法是将对象放在List/Vector中,然后为每种类型的标识符创建一个映射。很快我就意识到std-container不支持存储引用。
下一个想法是将对象保留在向量中,并将索引放在映射中。这里的问题是,我没有为vector找到index_of,并且只有当没有人使用insert或erase操作时,将索引存储在对象中才有效。
创建对象时唯一的标识符是字符串,出于性能考虑,我不想使用这个字符串作为映射的标识符。
这个问题是最好的解决与指针或谁有一个想法如何处理它?
谢谢
使用指针似乎很合理。以下是您可以实现的一个建议API:
class WidgetDatabase {
public:
// Returns true if widget was inserted.
// If there is a Widget in *this with the same name and/or id,
// widget is not inserted.
bool Insert(const std::string& name, int id, const Widget& widget);
// Caller does NOT own returned pointer (do not delete it!).
// null is returned if there is no such Widget.
const Widget* GetByName(const string& name) const;
const Widget* GetById(int id) const;
private:
std::set<Widget> widgets_;
std::map<std::string, Widget*> widgets_by_name_;
std::map<int, Widget*> widgets_by_id_;
};
我认为这应该很容易实现。您只需要确保维护以下不变式:
w在widgets_中,如果指向它的指针在widgets_by_*
我认为您将遇到的主要陷阱是确保在调用Insert时名称和id不在widgets_by_*中。
使这个线程安全应该很容易;只要加入一个mutex
成员变量,和一些局部的lock_guards
。可以选择在Get*
方法中使用shared_lock_guard
来避免争用;如果您的用例涉及更多的阅读而不是书写,这将特别有用。
您考虑过内存中的SQLite数据库吗?SQL为访问相同的数据提供了多种方法。例如,您的模式可能如下所示:
CREATE TABLE Widgets {
-- Different ways of referring to the same thing.
name STRING,
id INTEGER,
-- Non-identifying characteristics.
mass_kg FLOAT,
length_m FLOAT,
cost_cents INTEGER,
hue INTEGER;
}
然后可以使用不同的标识符进行查询:
SELECT mass_kg from Widgets where name = $name
或
SELECT mass_kg from Widgets where id = $id
当然,SQL允许您做的远不止这些。这将允许您在将来轻松扩展库的功能。
另一个优点是SQL是声明性的,这通常使它更简洁和可读。
在最近的版本中,SQLite支持对同一个数据库的并发访问。随着时间的推移,并发模型变得越来越强大,因此您必须确保了解所使用的版本所提供的模型。最新版本的文档可以在sqlite的网站上找到相关文章:
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- 用于访问容器<T>数据成员的正确 API
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 访问者访问变体并返回不同类型时出错
- 尝试通过多个向量访问变量时,向量下标超出范围
- 无法访问嵌套类.类的使用无效
- 写入位置0x0000000C时发生访问冲突
- 我们可以访问一个不存在的联盟的成员吗
- C++从另一个类访问公共静态向量的正确方法是什么
- 我的简单if-else语句是如何无法访问的代码
- 从C++dll访问C#中的一行主要参数
- 从子类访问模板类成员时出现"找不到标识符"错误
- 从<T>派生类访问 Base 标识符是否必须>?
- 使用标识符前缀访问枚举
- C 中类的定义和访问标识符
- 链接列表头节点标识符/指针访问问题
- 在访问多维数组的内置数组和初始化器列表时交换标识符和下标
- 哪些容器存储通过不同标识符访问的对象