我目前正在研究一个包含两个部分的项目。我有book.hWarehouse.h文件。 book存储有关书籍的信息,而warehouse保留书籍和书籍数量。我正在为此项目使用链接列表和指针。

这些是我的book流运算符:

friend istream& operator >> (istream& is, Book&book);
friend ostream& operator << (ostream& os, const Book&book);


这些是我的warehouse流运算符:

friend istream& operator >> (istream& is, Warehouse& warehouse);
friend ostream& operator << (ostream& os, const Warehouse& warehouse)


我的warehouse私有变量:

private:
    Book* head;
    int bookCount;


在我的上一个项目中,我们使用了数组,我只是将is >> warehouse.book[numofbooks]用于istream重载放在warehouse.cpp中。

对于这个项目,我尝试做is >> warehouse.head,但是我不确定那是正确的。

我的主文件如下所示:

#include "Book.h"
#include "Warehouse.h"
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char* argv[])
{
  bool found;
  Warehouse warehouse;
  Book book;
  string filename=argv[1];  //assigns the filename from console to a string

  ifstream is;
  is.open(filename);

  if(is.fail())       //check if the file was opened
  {
    cout<< "Unable to read file: " << filename<< endl;    //if not opened, tell user
    return -1;
  }

  is >> warehouse;

  is.close();
}

最佳答案

您显示的代码很好。问题所在是您未显示的代码。

在链接列表中,需要动态分配其节点。对于您的流运算符实现,我建议如下所示:

book.h

#include <iostream>

class Book
{
public:
    // fields as needed ...

    friend std::istream& operator >> (std::istream& is, Book& book);
    friend std::ostream& operator << (std::ostream& os, const Book& book);
};


book.cpp

#include "book.h"

std::istream& operator >> (std::istream& is, Book& book)
{
    // read book fields as needed...
    return is;
}

std::ostream& operator << (std::ostream& os, const Book& book)
{
    // write book fields as needed...
    return os;
}


仓库

#include <iostream>
#include "book.h"

class Warehouse
{
private:
    struct ListItem
    {
        ListItem* next = nullptr;
        Book book;

        ListItem(const Book &b) : book(b) {}
    };

    ListItem *head = nullptr;
    int bookCount = 0;

public:
    // fields as needed...

    void clear();
    // other methods as needed...

    friend std::istream& operator >> (std::istream& is, Warehouse& warehouse);
    friend std::ostream& operator << (std::ostream& os, const Warehouse& warehouse)
};


Warehouse.cpp

#include "warehouse.h"

void Warehouse::clear()
{
    ListItem *item = head;
    head = nullptr;
    bookCount = 0;

    while (item)
    {
        ListItem *next = item->next;
        delete item;
        item = next;
    }
}

std::istream& operator >> (std::istream& is, Warehouse& warehouse)
{
    warehouse.clear();

    int count;
    if (is >> count)
    {
        Warehouse::ListItem **item = &(warehouse.head);

        Book book;
        for (int i = 0; i < count; ++i)
        {
            if (!(is >> book)) return;
            *item = new Warehouse::ListItem(book);
            warehouse.bookCount++;
            item = &(item->next);
        }
    }

    return is;
}

std::ostream& operator << (std::ostream& os, const Warehouse& warehouse)
{
    os << warehouse.bookCount;

    Warehouse::ListItem *item = warehouse.head;
    for(int i = 0; i < warehouse.bookCount; ++i)
    {
        os << item->book;
        item = item->next;
    }
}


话虽如此,通过使用Warehouse代替手动的链表实现,可以将std::list简化一些:

仓库

#include <iostream>
#include <list>
#include "book.h"

class Warehouse
{
private:
    std::list<Book> books;

public:
    // fields as needed...

    void clear();
    // other methods as needed...

    friend std::istream& operator >> (std::istream& is, Warehouse& warehouse);
    friend std::ostream& operator << (std::ostream& os, const Warehouse& warehouse)
};


Warehouse.cpp

void Warehouse::clear()
{
    books.clear();
}

std::istream& operator >> (std::istream& is, Warehouse& warehouse)
{
    warehouse.clear();

    std::size_t count;
    if (is >> count)
    {
        Book book;
        for (std::size_t i = 0; i < count; ++i)
        {
            if (!(is >> book)) return;
            warehouse.books.push_back(book);
        }
    }

    return is;
}

std::ostream& operator << (std::ostream& os, const Warehouse& warehouse)
{
    os << warehouse.books.size();
    for(const Book &book : warehouse.books)
        os << book;
}

09-26 09:06