1

在使用了各种搜索引擎(以及出色的 stackoverflow 数据库)后,我发现了一些类似的情况,但它们要么复杂得多,要么不如我想要完成的复杂。

使用模板的 C ++ 列表循环链接错误C++:链接列表排序 指针地址在链接列表中不会更改

我正在尝试使用链接列表和节点模板来存储和打印非标准类对象(在这种情况下,是分类联系人的集合)。特别是,我想从一堆具有不同类别的对象中打印多个具有相同类别的对象。按类别打印时,我将子对象 tmpCategory (= "business") 与分类联系人的类别部分进行比较。

但是如何提取这些数据以在 int main() 中进行比较?

这就是我的想法。我在 LinkList.tem 中创建了一个 GetItem 成员函数,这将初始化指针光标,然后运行 ​​For 循环,直到函数输入与迭代次数匹配。此时,GetItem 使用 (cursor -> data) 返回对象类型。

template <class Type>
Type LinkList<Type>::GetItem(int itemNumber) const
{
    Node<Type>* cursor = NULL;

    for(cursor = first;
        cursor != NULL;
        cursor = (cursor -> next))
    {
        for(int i = 0; i < used; i++)
        {
            if(itemNumber == i)
            {
                return(cursor -> data);
            }
        }
    }
}

这就是 int main() 的用武之地。我将比较对象 tmpCategory 设置为某个值(在本例中为“Business”)。然后,我运行一个 For 循环,该循环的循环次数等于我拥有的节点数(由函数 GetUsed() 确定)。在该循环中,我使用当前的迭代编号调用 GetItem。从理论上讲,这将使 int 主循环从 LinkList.tem 返回相应的节点。从那里,我从该节点数据(当前有效)中的对象中调用类别,并将其与 tmpCategory 进行比较。如果匹配,循环将打印出整个 Node 的数据对象。

tmpCategory = "Business";

for(int i = 0; i < myCategorizedContact.GetUsed(); i++)
{
    if(myCategorizedContact.GetItem(i).getCategory() == tmpCategory)
       cout << myCategorizedContact.GetItem(i);
}

问题是当前的设置(当它运行时),它什么也没有返回。经过进一步测试( cout << myCategorizedContact.GetItem(i).getCategory() ),我发现它只是一遍又一遍地打印出第一个节点的类别。我希望整体方案评估每个节点并打印出匹配的数据,而不仅仅是吐出同一个节点。

非常感谢任何想法/建议。

4

1 回答 1

0

请仔细看看这个:

template <class Type>
Type LinkList<Type>::GetItem(int itemNumber) const
{
    Node<Type>* cursor = NULL;

    // loop over all items in the linked list    
    for(cursor = first;
        cursor != NULL;
        cursor = (cursor -> next))
    {
        // for each item in the linked list, run a for-loop 
        // counter from 0 to (used-1). 
        for(int i = 0; i < used; i++)
        {
            // if the passed in itemNumber matches 'i' anytime
            //  before we reach the end of the for-loop, return
            //  whatever the current cursor is.
            if(itemNumber == i)
            {
                return(cursor -> data);
            }
        }
    }
}

您不会将光标沿列表itemNumber时间向下移动。第一个项目cursor引用将启动内部循环。循环索引达到您返回的 itemNumber 的那一刻。如果链接列表中至少有itemNumber项目,则永远不会前进光标。. 事实上,它们中的两个(cursor 和 itemNumber)在你实现这个函数时是完全不相关的。并且真正增加讽刺的是,因为usedcursor完全不相关,如果used小于itemNumber总是如此,因为当通过外循环前进used时不会改变。cursor因此cursor最终变为 NULL 并且此函数的结果未定义(无返回值)。总之,正如所写的那样,您将始终返回第一项(如果itemNumber < used),或者由于没有返回值而未定义的行为。

我相信你需要类似以下的东西:

template< class Type >
Type LinkList<Type>::GetItem(int itemNumber) const
{
    const Node<Type>* cursor = first;
    while (cursor && itemNumber-- > 0)
        cursor = cursor->next;

    if (cursor)
        return cursor->data;

    // note: this is here because you're definition is to return
    //  an item COPY. This case would be better off returning a 
    //  `const Type*` instead, which would at least allow you to
    //  communicate to the caller that there was no item at the 
    //  proposed index (because the list is undersized) and return
    //  NULL, which the caller could check.
    return Type();
}
于 2012-11-10T09:18:49.583 回答