我使用 wxWidgets 树控件解决了类似的问题。我使用了一个单例引用计数器来跟踪我放入控件中的对象,并使用一个迭代器来遍历它们。这是一个例子。
class ReferenceCounter
{
public:
// Singleton pattern. Implementation left up to you.
static ReferenceCounter& get();
void add(const TreeData& data) {
mCounter[data.getId()].push_back(&data);
}
void remove(const TreeData& data) {
const CounterType::const_iterator itr = mCounter.find(data.getId());
if (itr != mCounter.end()) {
ItemType& items = itr->second;
items.erase(std::remove(items.begin(), items.end(), &data), items.end());
if (items.empty()) {
mCounter.erase(itr);
}
}
}
typedef std::vector<TreeData*> ItemType;
ItemType::iterator begin(const TreeData& data) {
const CounterType::const_iterator itr = mCounter.find(data.getId());
if (itr != mCounter.end()) {
return itr->second.begin();
}
// Else condition handling left up to you.
}
ItemType::iterator end(const TreeData& data) {
const CounterType::const_iterator itr = mCounter.find(data.getId());
if (itr != mCounter.end()) {
return itr->second.end();
}
// Else condition handling left up to you.
}
private:
typedef std::map<int, ItemType> CounterType;
CounterType mCounter;
};
class TreeData
{
public:
TreeData() { ReferenceCounter::get().add(*this); }
~TreeData() { ReferenceCounter::get().remove(*this); }
// Get database rows or whatever your tree is tracking.
int getId() const;
};
因此,给定任何 TreeData,您可以在引用计数器中查找所有其他具有匹配 id 的 TreeData。这使得保持名称和资料保持最新变得容易和快速。我们的树可以毫无问题地处理超过 1,000,000 个节点。在我的实现中,我将迭代内容封装在一个boost::iterator_facade
类中以便于使用。