I'm currently working on a project that has a couple of parts to it. I have book.h
and Warehouse.h
files. The book
stores information about a book while the warehouse
holds the books and number of books. I am using a linked list and pointers for this project.
These are my book
stream operators:
friend istream& operator >> (istream& is, Book&book);
friend ostream& operator << (ostream& os, const Book&book);
These are my warehouse
stream operators:
friend istream& operator >> (istream& is, Warehouse& warehouse);
friend ostream& operator << (ostream& os, const Warehouse& warehouse)
My warehouse
private variables:
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
.
For this project, I tried doing is >> warehouse.head
but I'm not sure that is correct.
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
#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;
}
}
That being said, Warehouse
can be simplified a bit by using std::list
instead of a manual linked-list implementation:
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.