简体   繁体   English

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

[英]Need to overload operator with Book* head variable but doesnt work

I'm currently working on a project that has a couple of parts to it. 我目前正在研究一个包含两个部分的项目。 I have book.h and Warehouse.h files. 我有book.hWarehouse.h文件。 The book stores information about a book while the warehouse holds the books and number of books. book存储有关book信息,而warehouse存放书籍和书籍数量。 I am using a linked list and pointers for this project. 我正在为此项目使用链接列表和指针。

These are my book stream operators: 这些是我的book流运算符:

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

These are my warehouse stream operators: 这些是我的warehouse流操作员:

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

My warehouse private variables: 我的warehouse私有变量:

private:
    Book* head;
    int bookCount;

In my previous project, we used arrays and I would just put is >> warehouse.book[numofbooks] for the istream overload in the warehouse.cpp . 在我以前的项目中,我们使用数组,我只想把is >> warehouse.book[numofbooks]istream过载warehouse.cpp

For this project, I tried doing is >> warehouse.head but I'm not sure that is correct. 对于这个项目,我尝试做的is >> warehouse.head但是我不确定那是正确的。

My main file looks like: 我的主文件如下所示:

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

The code you have shown is fine. 您显示的代码很好。 The code you have not shown is where the problem is. 问题所在是您未显示的代码。

In a linked list, its nodes need to be allocated dynamically. 在链接列表中,需要动态分配其节点。 I would suggest something like the following for your stream operator implementations: 对于您的流运算符实现,我建议如下所示:

book.h 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 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 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 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;
    }
}

That being said, Warehouse can be simplified a bit by using std::list instead of a manual linked-list implementation: 话虽如此,通过使用std::list而不是手动的链表实现,可以简化Warehouse

warehouse.h 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 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM