我正在尝试用C ++(oop风格)创建一个简单的图书馆系统,但是从第一课开始,我遇到了一些设计程序。
这是我的小书类.h文件(只是一个让我们说的草稿)。
#ifndef BOOKS_H
#define BOOKS_H
#include <string>
class Books
{
public:
Books();
~Books() {};
void createBook();
//void getBook();
private:
std::string mBookName;
std::string mBookAuthor;
int mId;
};
#endif
我想创建图书并将它们添加到文件中。
我的问题/疑问如下:
我应该使用作者和标题的数据成员,还是只使用下面的函数更新文件?
void Books::createBook()
{
std::string bookAuthor;
std::string bookName;
std::cout << "Enter the book Author\n";
std::getline (std::cin, bookAuthor);
//write to file bookAuthor
std::cout << "Enter the book name\n";
std::getline (std::cin, bookName);
//write to file bookName
mId++;
//write to file mId;
}
我在想如果我有一个数据成员作者和数据成员Title,那么如果我要将文章添加到文件中,那么我将在main
函数中编写与书籍一样多的书籍对象它会使代码复杂化..
相反,我正在考虑这样做:
int main()
{
Book newBook;
//some code to ask to user to enter an option to add a new book
newBook.createBook();
//rest of the code
return 0;
}
那么......哪个选项更好?
谢谢!
答案 0 :(得分:1)
我会通过思考一个真正的图书馆如何运作来解决这个问题。
您可以前往图书馆查找特定作者的书籍 您可以前往图书馆查找具有特定名称的图书。
每本书本身都是一个独特的对象,具有不变的名称和作者。
因此,我将其建模为单个Library
对象,其中包含多个Book
个对象。
Library
界面允许您添加图书,查找具有给定名称的所有图书,查找给定作者的所有图书等。
Book
界面可让您查找图书的名称及其作者。
图书馆必须管理一系列图书。我会尝试将STL用于我的书籍集合,因为这应该是您在C ++中使用数据结构的第一个资源。
std::map
允许您存储键/值对。 key
就像书的名字或作者一样 - 你想用它来查找书籍。
value
就是本书。
在这个特定的例子中,我会选择一个std::multimap
,因为这允许多个key
。这是因为您可以获得同一作者的多本书,并且您可以获得多本同名书籍。
我希望每个multimap
有一个key
我想要搜索 - 所以这里我有2个 - 一个用于键入名称的书籍,另一个用于键入作者的书籍。
multimap
有一个成员函数equal_range
,它允许我们使用相同的键查找所有值。
它返回两个迭代器,用于描述具有指定键的值范围。
然后,您可以向Library
类添加其他接口,以便将所有书籍保存到文件中,或者从文件中加载等等。
如下所示:
class Book
{
public:
Book(std::string author, std::string name)
: _author(std::move(author))
, _name(std::move(name))
{}
const std::string& author() const { return _author; }
const std::string& name() const { return _name; }
private:
const std::string _author;
const std::string _name;
};
class Library
{
using BookMap = std::multimap<std::string, std::shared_ptr<Book>>;
public:
void loadFromFile(const std::string& filename);
void saveToFile (const std::string& filename);
void addBook(std::string name, std::string author)
{
auto book = std::make_shared<Book>(std::move(name), std::move(author));
_books_by_name.emplace(book->name(), book);
_books_by_author.emplace(book->author(), book);
}
std::pair<BookMap::const_iterator, BookMap::const_iterator> findByName(const std::string& name)
{
return _books_by_name.equal_range(name);
}
std::pair<BookMap::const_iterator, BookMap::const_iterator> findByAuthor(const std::string& author)
{
return _books_by_author.equal_range(author);
}
private:
BookMap _books_by_name;
BookMap _books_by_author;
}