需要使用Book * head变量重载运算符,但不起作用

时间:2019-04-24 15:29:12

标签: c++ class pointers linked-list operator-overloading

我目前正在从事一个包含两个部分的项目。我有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();
}

1 个答案:

答案 0 :(得分:1)

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

在链接列表中,需要动态分配其节点。对于您的流运算符实现,我建议使用类似以下的内容:

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;
}

warehouse.h

#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而不是手动的链表实现来简化:

warehouse.h

#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;
}