我目前正在研究一个包含两个部分的项目。我有book.h
和Warehouse.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;
}