-1

我正在创建一个应用程序来跟踪书店库存。它会将包含信息的文本文件的文件路径作为 main 的参数。我遇到的问题似乎是每当我尝试访问用于存储我的 Item 对象的类状态向量清单的元素时。首先是类头,然后是方法定义,然后是 main。提前致谢。

    #ifndef _BOOKSTORE_H_
    #define _BOOKSTORE_H_

    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>
    #include <algorithm>
    #include <iterator>
    #include <stdlib.h>

    #include "Item.h"
    #include "Paperback.h"
    #include "Hardcover.h"
    #include "Audiobook.h"
    #include "Ebook.h"

    using namespace std;

    class Bookstore {

    //States
    private:
        vector<Item*> inventory;
    //Behaviors
    public: 
        Bookstore();
        void loadInventory(const char*);
        void searchInventory(string);
        unsigned int inventorySize();
        void printInventory();
        vector<string> split(string);

    };

    #endif


    #include "Bookstore.h"

    Bookstore::Bookstore() {}

    void Bookstore::loadInventory(const char* filepath) {

        string ty = "";
        string ti = "";
        string au = "";
        string pri = "";
        string f = "";
        string cd = "";
        string pro = "";

        string line;
        ifstream ifs;
        ifs.open (filepath);

        if (ifs.is_open()) {
            while (ifs.good()) {
                ty = "";
                ti = "";
                au = "";
                pri = "";
                f = "";
                cd = "";
                pro = "";

                getline(ifs, line);

                if (line.compare("Paperback") == 0) {
                    ty = "Paperback";
                    getline(ifs, line);
                    ti = line;
                    getline(ifs, line);
                    au = line;
                    getline(ifs, line);
                    pri = line;
                    Paperback p(ty, ti, au, pri);
                    inventory.push_back(&p);
                }

                if (line.compare("Hardcover") == 0) {
                    ty = "Hardcover";
                    getline(ifs, line);
                    ti = line;
                    getline(ifs, line);
                    au = line;
                    getline(ifs, line);
                    pri = line;
                    getline(ifs, line);
                    f = line;
                    Hardcover h(ty, ti, au, pri, f);
                    inventory.push_back(&h);
                }

                if (line.compare("Audio") == 0) {
                    ty = "Audio";
                    getline(ifs, line);
                    ti = line;
                    getline(ifs, line);
                    au = line;
                    getline(ifs, line);
                    pri = line;
                    getline(ifs, line);
                    cd = line;
                    Audiobook a(ty, ti, au, pri, cd);
                    inventory.push_back(&a);
                }

                if (line.compare("Electronic") == 0) {
                    ty = "Electronic";
                    getline(ifs, line);
                    ti = line;
                    getline(ifs, line);
                    au = line;
                    getline(ifs, line);
                    pri = line;
                    getline(ifs, line);
                    pro = line;
                    Ebook e(ty, ti, au, pri, pro);
                    inventory.push_back(&e);            
                }

            }
        }

        ifs.close();
        cout << inventory.size() << endl;

        for (unsigned int i=0; i<inventory.size(); i++) {
            inventory.at(i)->printItem();
        }
    }

    void Bookstore::searchInventory(string query) {

        vector<string> searchStr;
        int count;
        string currentStr;

            for (unsigned int i=0; i<inventory.size(); i++) {

                    currentStr = inventory.at(i)->getTitle();
                    searchStr = split(currentStr);

                    for(unsigned int j = 0; j < searchStr.size(); j++) {
                        if (searchStr[j].compare(query)==0) {
                            inventory.at(i)->printItem();
                            count++;
                        }
                    }

                    currentStr = inventory.at(i)->getAuthor();
                    searchStr = split(currentStr);

                    for(unsigned int j = 0; j < searchStr.size(); j++) {
                        if (searchStr[j].compare(query)==0) {
                            inventory.at(i)->printItem();
                            count++;
                        }
                    }

                    if ((i==(inventory.size()-1))&&(count==0)) {
                        cout << "Sorry, no matching results were found." << endl;
                    } else if ((i==(inventory.size()-1))&&(count!=0)) {
                        cout << "Query complete." << endl;
                    }
            }
    }

    unsigned int Bookstore::inventorySize() {
        unsigned int num = inventory.size();
        return num;
    }

    void Bookstore::printInventory() {
        for (unsigned int i = 0; i < inventory.size(); i++) {
            inventory.at(i)->printItem();       
        }

    }

    vector<string> Bookstore::split(string s) {
        vector<string> pieces;
        istringstream iss(s);
        copy(istream_iterator<string>(iss), istream_iterator<string>(),
            back_inserter<vector<string> >(pieces));

        return pieces;
    }

    #include "Bookstore.h"

    int main(int argc, char** argv) {

        Bookstore current;

        if (argc==2) {
            current.loadInventory(argv[1]);
        }

        cout << current.inventorySize() << endl;

        //Initialize variables
        char status = 'R';
        string input = "";
        int iter = 1;

        //Run application until quit
        while (status=='R') {

            //Provide menu
            if (iter==1) {
                cout << "Welcome to Bookstore Inventory 9000." << endl;
            }

            if (current.inventorySize()==0) {
                    cout << "There are no entries!" << endl;
                    status = 'Q';
            } else {

                cout << "Would you like to (V)iew all, (S)earch, or (Q)uit?" << endl;

                getline(cin, input);

                if (input.compare("V")==0) {
                    current.printInventory();       
                } else if (input.compare("S")==0) {
                    cout << endl;
                    cout << "What are you looking for?" << endl;
                    getline(cin, input);
                    current.searchInventory(input);
                    cout << endl;
                } else if (input.compare("Q")==0) {
                    status = 'Q';
                    cout << "Thank you for perusing our inventory. Goodbye." << endl;
                } else {
                    cout << endl;
                    cout << "This is not a valid choice. Please try again." << endl;
                    cout << endl;
                }
            }

            iter++;

        }

    return -1;

    }
4

1 回答 1

1

你的问题不在于at(). 您的问题是您将地址存储到局部变量,然后您使用该指针,即使局部变量不再存在。

具体来说,在 中loadInventory,这是一个示例:

 if (line.compare("Paperback") == 0) {
                ty = "Paperback";
                getline(ifs, line);
                ti = line;
                getline(ifs, line);
                au = line;
                getline(ifs, line);
                pri = line;
                Paperback p(ty, ti, au, pri);
                inventory.push_back(&p);
            }

请注意倒数第二行中如何创建名为“p”的本地(堆栈)变量。在最后一行,您获取该局部变量的地址并将其存储起来。一旦代码到达上面引用中的最后一个大括号,名为“p”的变量就会消失,向量中的那个指针就不再有用了。

一种可能的解决方案是动态分配:

Paperback* p = new Paperback(ty, ti, au, pri);
inventory.push_back(p);

inventory请注意,如果您这样做,一旦您的向量完成了这些指针,您就必须自己删除它们。

于 2012-10-01T03:12:32.723 回答