此管理系统相比于上一篇用Java实现的功能更多了,结构更加简单了,没有用继承之类的复杂语法。逻辑实现上更加严谨了,但是并没有异常处理,以及文件读取等持久化信息的操作,这些操作需要后续的学习。
功能概览
?
Library.h
BookRecord
#include<vector>
#include<cassert>
#include<string>
#include<iostream>
#include<map>
#include<set>
using namespace std;
// 图书类
class BookRecord
{
public:
BookRecord(string s1, string s2, string s3, string s4, unsigned int n1, unsigned int n2) :
book_title_(s1), book_isbn_(s2), author_(s3), year_published_(s4), number_of_copies_(n1), number_of_copies_available_(n2) {}
~BookRecord() = default;
void DisplayRecord()const; // 打印
bool loan_out(); // 书籍借出函数
void AddBook(int n) { number_of_copies_ += n; number_of_copies_available_ += n; } // 增添书籍
bool is_available()const { return number_of_copies_available_ > 0; } // 判断是否有余量。
bool deletebook()const { return number_of_copies_ == number_of_copies_available_; } // 删除书籍
void ReturnBook() { ++number_of_copies_available_; } // 归还书籍
const string& isbn()const { return book_isbn_; } // 返回ISBN
const string& name()const { return book_title_; } // 返回名字
private:
string book_title_;
string book_isbn_;
string author_;
string year_published_;
unsigned int number_of_copies_;
unsigned int number_of_copies_available_;
};
存储图书的基本信息,以及一些对外接口。?
Borrower
// 借阅人类
class Borrower
{
public:
Borrower(string id, string name, string tele)
:borrower_id_(id), name_(name), telephone_(tele){}
~Borrower() = default;
const string& id()const { return borrower_id_; }
const string& name()const { return name_; }
void DisplayRecord()const; // 打印函数
void LoanBook(const string& s); // 借书
bool ReturnBook(const string& s); // 还书
bool Logout()const { return book_loaned_ == 0; } // 注销
private:
string borrower_id_;
string name_;
string telephone_;
unsigned int book_loaned_ = 0;
vector<string> book_loaned_titles_ = vector<string>();
};
借阅人类,存储借阅人的基本信息,其中包括这个人借了哪些书,vector存储那些书籍的书名。?
Library
// 图书馆类
class Library
{
public:
Library() = default;
~Library()
{
for (const auto& i : vec_pbook_)
delete i;
for (const auto& i : vec_pborrower_)
delete i;
}
Library(const Library&) = delete;
Library& operator=(const Library&) = delete;
void DisplayAllBook()const; // 打印全部书籍
void DisplayAllBorrower()const; // 打印全部借阅人
void DisplayBook()const; // 打印特定书籍
void DisplayBorrower()const; // 打印特定借阅人
void AddBook(); // 添加书籍
void DeleteBook(); // 删除书籍
void LoanBook(); // 借书
void ReturnBook(); // 还书
void Register(); // 注册
void Logout(); // 注销
private:
vector<Borrower*> vec_pborrower_;
vector<BookRecord*> vec_pbook_;
map<string, Borrower*> map_borrower_; // 书籍的ISBN映射到书籍对象指针
map<string, BookRecord*> map_bookrecord_; // 借阅人id到借阅人对象指针的映射
};
数据成员有 借阅人对象指针的vector 和 书籍对象指针的vector。这里方便遍历。? 还有借阅人id到对象指针的map映射,方便通过id检索此人是否存在,以及对应对象的方法调用。?还有书籍isbn到书籍对象指针的map映射,同样也是方便检索。
成员函数就是那些功能的实现,都封装在了一个Library类的对象中。main.cpp中可以看到调用。
Library.cpp
BookRecord成员函数实现
#include"Library.h"
void BookRecord::DisplayRecord()const
{
auto c1 = book_title_.c_str(), c2 = book_isbn_.c_str(), c3 = author_.c_str(), c4 = year_published_.c_str();
printf("书名:%-10s ISBN:%-15s 作者:%-8s 出版年: %-5s 总数量:%d 余量:%d\n", c1, c2, c3, c4, number_of_copies_, number_of_copies_available_);
}
bool BookRecord::loan_out()
{
if (number_of_copies_available_ > 0)
{
--number_of_copies_available_;
return true;
}
else
{
return false;
}
}
loan_out 成员函数用于判断此书是否还有余量可以借出,用于LoanBook方法中。用返回值判断是否还有余量。?
Borrower成员函数实现
void Borrower::DisplayRecord()const
{
auto c1 = borrower_id_.c_str(), c2 = name_.c_str(), c3 = telephone_.c_str();
printf("ID:%-15s 姓名:%-5s 联系方式:%-15s 借阅书籍数量:%d\n", c1, c2, c3, book_loaned_);
if (book_loaned_ != 0)
{
cout << "借阅书籍名称" << ": ";
for (const auto& i : book_loaned_titles_)
cout << i << " ";
cout << endl;
}
}
void Borrower::LoanBook(const string& title)
{
++book_loaned_;
book_loaned_titles_.push_back(title);
}
bool Borrower::ReturnBook(const string& name)
{
for (auto i = book_loaned_titles_.begin(); i != book_loaned_titles_.end(); ++i)
{
if ((*i) == name)
{
book_loaned_titles_.erase(i);
--book_loaned_;
return true;
}
}
return false;
}
LoanBook用于辅助Library类的LoanBook的实现。ReturnBook需要将书籍名在对象的vector<string>中删除,还要将借书量减一。?
Library的打印函数实现
void Library::DisplayAllBook()const
{
if (!vec_pbook_.empty())
for (auto i : vec_pbook_)
i->DisplayRecord();
else
cout << "图书馆暂无书籍" << endl;
}
void Library::DisplayAllBorrower()const
{
if (!vec_pborrower_.empty())
for (auto i : vec_pborrower_)
i->DisplayRecord();
else
cout << "图书馆暂无借阅人" << endl;
}
void Library::DisplayBook()const
{
cout << "请输入书籍名称" << endl;
string name;
cin >> name;
for (const auto& i : vec_pbook_)
if (i->name() == name)
{
i->DisplayRecord();
return;
}
cout <<"错误," << name << "书籍不存在" << endl;
}
void Library::DisplayBorrower()const
{
cout << "请输入借阅人姓名" << endl;
string name;
cin >> name;
for(const auto& i :vec_pborrower_)
if (i->name() == name)
{
i->DisplayRecord();
return;
}
cout << "错误" << name << "借阅人不存在" << endl;
}
略?
LoanBook + ReturnBook? 借书+还书
void Library::LoanBook()
{
cout << "请输入你的id号码" << endl;
string id;
cin >> id;
if (map_borrower_.find(id) == map_borrower_.end())
{
cout << "错误,你尚未注册,无法借书" << endl;
cout << "是否注册?(Y/N)" << endl;
char input = ' ';
cin >> input;
if (input == 'Y' || input == 'y')
Register();
return;
}
cout << "请输入你想借阅的书籍书名" << endl;
string name;
cin >> name;
for (auto i = vec_pbook_.begin(); i != vec_pbook_.end(); ++i)
{
// 这里用到了vector_pbook
if ((*i)->name() == name)
{
if ((*i)->loan_out())
{
map_borrower_[id]->LoanBook(name);
cout << "借阅成功" << endl;
}
else
cout << "书籍余量为零,借阅失败" << endl;
return;
}
}
cout << name << "书籍不存在" << endl;
}
void Library::ReturnBook()
{
cout << "请输入你的id号码" << endl;
string id;
cin >> id;
if (map_borrower_.find(id) == map_borrower_.end())
{
cout << "错误,你尚未注册,无法归还书籍" << endl;
cout << "是否注册?(Y/N)" << endl;
char input = ' ';
cin >> input;
if (input == 'Y' || input == 'y')
Register();
return;
}
cout << "请输入你要归还书籍的ISBN编号" << endl;
string isbn;
cin >> isbn;
if (map_bookrecord_.find(isbn) == map_bookrecord_.end())
{
cout << "错误,图书馆不存在此书" << endl;
return;
}
auto name = map_bookrecord_[isbn]->name();
if (map_borrower_[id]->ReturnBook(name))
{
map_bookrecord_[isbn]->ReturnBook();
return;
}
else
cout << "错误,检测到你尚未借过此书" << endl;
}
逻辑较为缜密? ?借书和还书时,借阅人那里和书籍那里都要处理。?
AddBook + DeleteBook 添加书籍 删除书籍? 这是管理员的功能
void Library::AddBook()
{
string title, isbn, author, published;
unsigned int copies;
cout << "请输入书名,ISBN编号,作者名,出版年,数量。中间以空格隔开" << endl;
cin >> title >> isbn >> author >> published >> copies;
if (map_bookrecord_.find(isbn) == map_bookrecord_.end())
{
BookRecord* p = new BookRecord(title, isbn, author, published, copies, copies);
assert(p);
vec_pbook_.push_back(p);
map_bookrecord_.insert({ p->isbn(),p });
}
else
map_bookrecord_[isbn]->AddBook(copies);
cout << "添加成功" << endl;
}
void Library::DeleteBook()
{
string isbn;
cout << "请输入你要删除的书籍ISBN号码:>" << endl;
cin >> isbn;
if (map_bookrecord_.find(isbn) == map_bookrecord_.end())
{
cout << "错误,该书籍不存在!!!" << endl;
return;
}
else if (map_bookrecord_[isbn]->deletebook() == false)
{
cout << "错误,此书籍尚未全部归还!!!" << endl;
return;
}
auto p = map_bookrecord_[isbn];
map_bookrecord_.erase(isbn);
for (auto i = vec_pbook_.begin(); i != vec_pbook_.end(); ++i)
{
if (*i == p)
{
vec_pbook_.erase(i);
break;
}
}
delete p;
cout << "删除成功" << endl;
}
?vector和map中都要处理信息。不过是书籍的vector和map
Register + Logout? 注册 注销 用于借阅人的操作
void Library::Register()
{
string id;
cout << "请输入一个你自己的id号码" << endl;
do
{
cin >> id;
if (map_borrower_.find(id) != map_borrower_.end())
{
cout << "错误,此id已存在,请重新输入。" << endl;
}
else
break;
} while (true);
string name, tele;
cout << "请输入你的姓名,联系方式" << endl;
cin >> name >> tele;
Borrower* p = new Borrower(id, name, tele);
assert(p);
vec_pborrower_.push_back(p);
map_borrower_.insert({ id,p });
cout << "注册成功" << endl;
}
void Library::Logout()
{
cout << "请输入你的id号码" << endl;
string id;
cin >> id;
if (map_borrower_.find(id) == map_borrower_.end())
{
cout << "错误,你尚未注册" << endl;
cout << "是否注册?(Y/N)" << endl;
char input = ' ';
cin >> input;
if (input == 'Y' || input == 'y')
Register();
return;
}
else if (map_borrower_[id]->Logout() != true)
{
cout << "错误,注销失败,你有书籍尚未归还" << endl;
return;
}
auto p = map_borrower_[id];
for (auto i = vec_pborrower_.begin(); i != vec_pborrower_.end(); ++i)
if (*i == p)
{
vec_pborrower_.erase(i);
break;
}
map_borrower_.erase(id);
delete p;
cout << "注销成功" << endl;
}
vector和map都要处理。? 借阅人的vector和map
Main.cpp
#include"Library.h"
void menu()
{
cout << " 欢迎进入图书馆 " << endl;
cout << "==========================" << endl;
cout << " 1. 管理员系统 " << endl;
cout << " 2. 借阅人系统 " << endl;
cout << " 0. 退出系统 " << endl;
cout << "==========================" << endl;
}
void MenuOfManager()
{
cout << " 欢迎进入管理员系统 " << endl;
cout << "==============================" << endl;
cout << " 1. 查看全部书籍 " << endl;
cout << " 2. 查看全部借阅人 " << endl;
cout << " 3. 查找指定书籍 " << endl;
cout << " 4. 查找指定借阅人 " << endl;
cout << " 5. 添加书籍 " << endl;
cout << " 6. 删除书籍 " << endl;
cout << " 0. 退出系统 " << endl;
cout << "=============================" << endl;
}
void MenuOfReader()
{
cout << " 欢迎进入借阅人系统 *" << endl;
cout << "==============================" << endl;
cout << " 1. 查看全部书籍 " << endl;
cout << " 2. 查找指定书籍 " << endl;
cout << " 3. 借阅书籍 " << endl;
cout << " 4. 归还书籍 " << endl;
cout << " 5. 注册 " << endl;
cout << " 6. 注销 " << endl;
cout << " 0. 退出系统 " << endl;
cout << "==============================" << endl;
}
void manager(Library& lib)
{
int input = 0;
do
{
MenuOfManager();
printf("请输入你的选择:>");
cin >> input;
switch (input)
{
case 1:
lib.DisplayAllBook();
break;
case 2:
lib.DisplayAllBorrower();
break;
case 3:
lib.DisplayBook();
break;
case 4:
lib.DisplayBorrower();
break;
case 5:
lib.AddBook();
break;
case 6:
lib.DeleteBook();
break;
case 0:
cout << "退出成功" << endl;
break;
default:
cout << "输入错误,请重新输入" << endl;
break;
}
} while (input);
}
void reader(Library& lib)
{
int input = 0;
do
{
MenuOfReader();
printf("请输入你的选择:>");
cin >> input;
switch (input)
{
case 1:
lib.DisplayAllBook();
break;
case 2:
lib.DisplayBook();
break;
case 3:
lib.LoanBook();
break;
case 4:
lib.ReturnBook();
break;
case 5:
lib.Register();
break;
case 6:
lib.Logout();
break;
case 0:
cout << "退出成功" << endl;
break;
default:
cout << "输入错误,请重新输入" << endl;
break;
}
} while (input);
}
void test()
{
Library lib;
// Library lib2 = lib;
// lib2 = lib;
int input = 0;
do
{
menu();
printf("请输入你的选择:>");
cin >> input;
switch (input)
{
case 1:
manager(lib);
break;
case 2:
reader(lib);
break;
case 0:
cout << "退出成功" << endl;
break;
default:
cout << "输入错误,请重新输入" << endl;
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
有点丑陋了,全是switch case语句。
综上,就是STL的容器练习,以及类和对象的使用。
|