我的C ++列表迭代器是在改变位置,还是我做错了什么?

时间:2014-03-23 19:06:59

标签: c++ list iterator

我正在研究rolodex并且已经达到了能够在列表中添加和搜索“卡片”的程度。但是,在我完成搜索并尝试查看当前的“卡片”(在当前迭代器位置)后,它给了我一些完全不同的东西。任何想法为什么会发生这种情况(代码摘录如下)?

Rolodex.h:

#ifndef _ROLODEX_H_
#define _ROLODEX_H_

#include <string>
#include <list>
#include <iterator>
#include <algorithm>

#include "Card.h"   //Card class definition

using namespace std;

class Rolodex
{
    public:
        void add(Card& card);
        Card getCurrentCard();
        bool search(const string&, const string&);
        void show(ostream&);
    private:
        list<Card> rolodex;
        list<Card>::iterator rolodexIt;
};

#endif

Rolodex.cpp:

#include <cctype>
#include <algorithm>
#include <cstring>

#include "Card.h"       //Card class definiton
#include "Rolodex.h"    //Rolodex class definition

using namespace std;

void Rolodex::add(Card& card)
{
    if (rolodex.empty())
    {
        rolodexIt = rolodex.begin();
        rolodex.insert(rolodexIt, card);
        return;
    }

    else
    {    
        rolodexIt = rolodex.begin();
        while (rolodexIt != rolodex.end())
        {
            if (!rolodexIt -> getLastName().compare(card.getLastName()) && !rolodexIt -> getFirstName().compare(card.getFirstName()))
            {
                rolodex.insert(rolodexIt, card);
                return;
            }

            else
            {
                int length;
                int roloLength = rolodexIt -> getLastName().size();
                int userLength = card.getLastName().size();

                if (roloLength < userLength)
                {
                    length = roloLength;
                }

                else
                {
                    length = userLength;
                }

                for (int i = 0; i < length; i++)
                {
                    char rolo = rolodexIt -> getLastName().at(i);
                    char user = card.getLastName().at(i);

                    if (rolo > user)
                    {
                        rolodex.insert(rolodexIt, card);
                        return;
                    }

                    else if (rolo < user)
                    {
                        break;
                    }
                }

                rolodexIt++;
            }
        }

        rolodexIt = rolodex.end();
        rolodex.insert(rolodexIt, card);
    }
}

Card Rolodex::getCurrentCard()
{
    return *rolodexIt;
}

bool Rolodex::search(const string& lastName, const string& firstName)
{
    list<Card>::iterator tempIt = rolodexIt;

    rolodexIt = rolodex.begin();

    while (rolodexIt != rolodex.end())
    {
        if (!rolodexIt -> getLastName().compare(lastName) && !rolodexIt -> getFirstName().compare(firstName))
        {
            return true;
        }

        else
        {
            rolodexIt++;
        }
    }

    cout << endl << "No exact matches found: Displaying closest match." << endl;
    rolodexIt = rolodex.begin();

    while (rolodexIt != rolodex.end())
    {        
        int length;
        int roloLength = rolodexIt -> getLastName().size();
        int userLength = lastName.size();

        if (roloLength < userLength)
        {
            length = roloLength;
        }

        else
        {
            length = userLength;
        }

        for (int i = 0; i < length; i++)
        {
            char rolo = rolodexIt -> getLastName().at(i);
            char user = lastName.at(i);

            if (rolo == user)
            {
                if (roloLength < userLength && i + 1 == roloLength)
                {
                    rolodexIt++;
                    return true;
                }

                else if (roloLength > userLength && i + 1 == userLength)
                {
                    return true;
                }
            }

            else if (rolo > user)
            {
                return true;
            }

            else if (rolo < user)
            {
                break;
            }
        }

        rolodexIt++;
    }

    rolodexIt = tempIt;
    return false;         
}

void Rolodex::show(ostream& os)
{
    list<Card>::iterator tempIt = rolodexIt;

    for (rolodexIt = rolodex.begin(); rolodexIt != rolodex.end(); rolodexIt++)
    {
        rolodexIt -> show(os);
    }

    rolodexIt = tempIt;
}

的main.cpp

#include <iostream>
#include <cstring>

#include "Card.h"       //Card class definition
#include "Rolodex.h"    //Rolodex class definition

using namespace std;

void listDex(Rolodex temp)
{
    temp.show(cout);
}

void view(Rolodex temp)
{
    temp.getCurrentCard().show(cout);
}

void search(Rolodex temp)
{
    string lastName;
    string firstName;

    cout << endl << "Enter last and first names for search:" << endl;

    cout << "Last Name: ";
    cin >> lastName;

    cout << "First Name: ";
    cin >> firstName;

    if (temp.search(lastName, firstName))
    {
        view(temp);
    }
}

int quit()
{
    cout << endl << "Program ended." << endl;
    return 0;
}

int main(void)
{
    int status = 1;

    Rolodex testData;

    Card card[10];

    card[0].setFirstName("Tony");
    card[0].setLastName("Hansen");
    card[0].setOccupation("Writer");
    card[0].setAddress("12 E. St. NY, NY 33333");
    card[0].setPhoneNumber("555-9999");

    card[1].setFirstName("Jon");
    card[1].setLastName("Smyth");
    card[1].setOccupation("Computer Hardware");
    card[1].setAddress("CMU Computer Services\nPittsburgh, PA");
    card[1].setPhoneNumber("555-1324");

    for (int i = 0; i < 10; i++)
    {
        testData.add(card[i]);
    }

    listDex(testData);
    search(testData);
    view(testData);
    quit();
}

我试图减少代码的内容,但它看起来仍然很长...抱歉。 = /

基本上,我遇到的问题是我打电话时

view(testData);

它返回的内容与我刚刚用

查看的内容完全不同
search(testData);

任何帮助,建议和建设性批评都表示赞赏。谢谢你的时间!

1 个答案:

答案 0 :(得分:2)

view()search()按值传递Rolodex对象。这意味着为search()的第一次调用生成了一个新对象,副本&#39;迭代器在search()内被修改。这些修改不会对testData Rolodex对象进行,后者会传递给view(),因此无法按预期工作。

你应该通过引用或指针传递它们。

另请注意,您正在访问card[0..9],即使您只是显式初始化了前两个。如果Card构造函数正确初始化对象,这可能仍然可以。