ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 13.4 wxList和wxNode wxList类是一个双向链表,可以用来存储任何类型的数据.wxWidgets需要你显式的定义一个针对某种数据类型的新的类来使用它,以便对存储于其中的数据提供足够的类型检查.wxList类还允许你指定一个索引类型以便进行基本的查找操作(如果你想使用基于结构的快速随机访问,请参考下一节的 wxHashMap类). wxList使用了一个虚类wxNode.当你定义一个新的wxList派生类的时候,你同时定义了一个派生自wxNodeBase的类,以便对节点提供类型安全检查.节点类最重要的函数包括:GetNext,GetPrevious和GetData.它们的功能显而易见,分别为:获取下一个子项,获取前一个子项以及获取子项的数据. 唯一值得说明的是wxList的删除操作,默认情况下,从链表中移除一个节点并不会导致节点内部数据的释放.你需要调用 DeleteContents函数来改变这种默认的行为,设置数据随着节点一起释放.如果你想清除整个链表并且释放其中的数据,你应该先调用 DeleteContents,参数为True,然后再调用Clear函数. 我们用不着在这里把手册的内容重新粘贴一遍.我们将举一个简单的例子来演示怎样创建你自己的链表类型.注意WX_DECLARE_LIST宏通常应该位于头文件中,而WX_DEFINE_LIST宏通常应该位于源文件中. ``` // 我们将存储于链表的数据类型 class Customer { public: int CustID; wxString CustName; }; // 通常应该位于头文件中 WX_DECLARE_LIST(Customer, CustomerList); // 下面的定义应该位于源文件中,并且通常位于所有Customer声明之后 #include <wx/listimpl.cpp> WX_DEFINE_LIST(CustomerList); // 用于排序的比较函数 int listcompare(const Customer** arg1, const Customer** arg2) { return ((*arg1)->CustID < (*arg2)->CustID); } // 链表操作举例 void ListTest() { // 定义一个我们自定义链表的实例 CustomerList* MyList = new CustomerList(); bool IsEmpty = MyList->IsEmpty(); // will be true // 创建一些自定义对象实例 Customer* CustA = new Customer; CustA->CustID = 10; CustA->CustName = wxT("Bob"); Customer* CustB = new Customer; CustB->CustID = 20; CustB->CustName = wxT("Sally"); Customer* CustC = new Customer; CustC->CustID = 5; CustC->CustName = wxT("Dmitri"); // 将其增加到链表中 MyList->Append(CustA); MyList->Append(CustB); // 实现随机插入 MyList->Insert((size_t)0, CustC); int Count = MyList->GetCount(); // will be 3 // 如果找不到,返回wxNOT_FOUND int index = MyList->IndexOf(CustB); // will be 2 // 自定义的节点里包含了我们自定义的类型 CustomerList::Node* node = MyList->GetFirst(); // 节点遍历 while (node) { Customer* Cust = node->GetData(); // 进行一些处理 node = node->GetNext(); } // 返回特定位置的节点 node = MyList->Item(0); // 按照排序函数排序 MyList->Sort(listcompare); // 移除包含某个对象的节点 MyList->DeleteObject(CustA); // 我们需要自己释放这个对象 delete CustA; // 找到包含某个对象的节点 node = MyList->Find(CustB); // 指示内部数据随节点的删除而删除 MyList->DeleteContents(true); // 删除B的节点的时候,B也被释放了 MyList->DeleteNode(node); // 现在调用Clear,所有的节点和其中数据都将被释放 MyList->Clear(); delete MyList; } ```