A library maintains a collection of books. Books can be added to and deleted fro
ID: 3861326 • Letter: A
Question
A library maintains a collection of books. Books can be added to and deleted from and checked out and checked in to this collection.
Title and author name identify a book. Each book object maintains a count of the number of copies available and the number of copies checked out. The number of copies must always be greater than or equal to zero. If the number of copies for a book goes to zero, it must be deleted from the library’s collection. When a book is checked out, checkouts are incremented; when a book is checked in, checkouts are decremented. The number of checkouts must always be greater than or equal to zero and less than or equal to the number of copies available.
If an exception occurs when calling a member function, throw a “logic_error” with a descriptive error message. To access “logic_error,” include the “stdexcept” library. For example, when attempting to check out a book, if no copies of the book exist, throw a “logic_error” stating that the title was not found: “throw logic_error(title + " not found.");”.
Each class requires a separate header and implementation file, for example, “Library.h” and “Library.cpp.” Do not place implementation code in the header file; you will lose points for this. The class header and implementation files must be contained within the “cs20a” namespace. All member functions in the class diagram must be implemented; no additional member functions are needed.
Implement the Book and Library classes. Download the code provided by the instructor for the DynamicArray, the Book and Library header and implementation files, and the Library driver: Library Management System.
Library.h
#pragma once
#include <iostream>
#include <string>
namespace cs20a {
using namespace std;
class Book
{
public:
Book();
Book(string author, string title, int copies = 1, int checkedOut = 0);
string getAuthor() const;
string getTitle() const;
void setAuthor(string author);
void setTitle(string title);
int getCopies() const;
int getCheckedOut() const;
void addCopy();
void deleteCopy();
void checkOut();
void checkIn();
friend ostream& operator << (ostream& outs, const Book& book);
private:
string author, title;
int copies, checkedOut;
};
}
Library.cpp
#include <stdexcept>
#include "Library.h"
namespace cs20a {
Library::Library()
{}
ostream & operator<<(ostream & outs, const Library & library)
{
for (int i = 0; i < library.getTotalBooks(); i++)
outs << library.books[i] << endl;
return outs;
}
//*** Code goes here ***//
//*** Code goes here ***//
//*** Code goes here ***//
}
Book.h
#pragma once
#include <iostream>
#include <string>
namespace cs20a {
using namespace std;
class Book
{
public:
Book();
Book(string author, string title, int copies = 1, int checkedOut = 0);
string getAuthor() const;
string getTitle() const;
void setAuthor(string author);
void setTitle(string title);
int getCopies() const;
int getCheckedOut() const;
void addCopy();
void deleteCopy();
void checkOut();
void checkIn();
friend ostream& operator << (ostream& outs, const Book& book);
private:
string author, title;
int copies, checkedOut;
};
}
Book.cpp
#include <stdexcept>
#include "Book.h"
namespace cs20a {
Book::Book() : author(), title(), copies(1), checkedOut(0)
{}
Book::Book(string author, string title, int copies, int checkedOut)
: author(author), title(title), copies(copies), checkedOut(checkedOut)
{}
ostream & cs20a::operator<<(ostream & outs, const Book & book)
{
cout << book.title << ", by " << book.author << " Copies: "
<< book.copies << " Checked out: " << book.checkedOut;
return outs;
}
//*** Code goes here ***//
//*** Code goes here ***//
//*** Code goes here ***//
}
Librarydriver.cpp
#include <iostream>
#include "Library.h"
#include "Book.h"
using namespace std;
using namespace cs20a;
int main()
{
Library library;
try
{
cout << "--> Before Initial State." << endl;
library.addBook("Ernest Hemingway", "For Whom the Bell Tolls");
library.addBook("Ernest Hemingway", "For Whom the Bell Tolls");
library.addBook("John Steinbeck", "The Grapes of Wrath");
library.addBook("John Steinbeck", "The Grapes of Wrath");
library.addBook("John Steinbeck", "East of Eden");
library.addBook("Mark Twain", "Huckleberry Finn");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After Initial State." << endl << endl;
try
{
cout << "--> Before deleting Main Street and For Whom the Bell Tolls." << endl;
if (library.hasBook("Sinclair Lewis", "Main Street"))
library.deleteBook("Sinclair Lewis", "Main Street");
library.deleteBook("Ernest Hemingway", "For Whom the Bell Tolls");
library.deleteBook("Ernest Hemingway", "For Whom the Bell Tolls");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After deleting Main Street and For Whom the Bell Tolls." << endl << endl;
try
{
cout << "--> Before checking out For Whom the Bell Tolls and The Grapes of Wrath." << endl;
if (library.hasBook("Ernest Hemingway", "For Whom the Bell Tolls"))
library.checkOutBook("Ernest Hemingway", "For Whom the Bell Tolls");
if (library.hasBook("John Steinbeck", "The Grapes of Wrath"))
library.checkOutBook("John Steinbeck", "The Grapes of Wrath");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After checking out For Whom the Bell Tolls and The Grapes of Wrath." << endl << endl;
try
{
cout << "--> Before checking checking in For Whom the Bell Tolls." << endl;
library.checkInBook("Ernest Hemingway", "For Whom the Bell Tolls");
library.checkInBook("Ernest Hemingway", "For Whom the Bell Tolls");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After checking checking in For Whom the Bell Tolls." << endl << endl;
try
{
cout << "--> Before checking in The Grapes of Wrath." << endl;
library.checkInBook("John Steinbeck", "The Grapes of Wrath");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After checking in The Grapes of Wrath." << endl << endl;
try
{
cout << "--> Before checking in Huckleberry Finn." << endl;
library.checkInBook("Mark Twain", "Huckleberry Finn");
cout << endl;
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After checking in Huckleberry Finn." << endl << endl;
system("pause");
return 0;
}
Dynamicarray.h
#pragma once
#include <stdexcept>
namespace cs20a
{
const int INITIAL_CAPACITY = 2;
const int GROWTH_FACTOR = 2;
const double MINIMUM_SIZE_ALLOWED = 0.25;
template<class T>
class DynamicArray
{
public:
DynamicArray();
DynamicArray(int capacity);
DynamicArray(const DynamicArray<T> &rhs);
~DynamicArray();
void add(const T& value);
void removeAt(int index);
void insert(int index, const T& value);
bool remove(const T& value);
int indexOf(const T& value) const;
bool contains(const T& value) const;
void clear();
int getSize() const;
int getCapacity() const;
bool isEmpty() const;
DynamicArray<T>& operator =(const DynamicArray<T>& rhs);
T& operator[](int index);
const T& operator[](int index) const;
bool operator==(DynamicArray<T> & a) const;
bool operator!=(DynamicArray<T> & a) const;
private:
int size, capacity;
T *elements;
void deepCopy(const DynamicArray<T>& rhs);
void setCapacity(int newCapacity);
bool isCapacityAdjustmentNeeded() const;
bool isIndexInRange(int index) const;
};
template<class T>
DynamicArray<T>::DynamicArray() : size(0), capacity(INITIAL_CAPACITY)
{
elements = new T[capacity];
}
template<class T>
DynamicArray<T>::DynamicArray(int capacity) : size(0), capacity(capacity)
{
elements = new T[capacity];
}
template<class T>
DynamicArray<T>::DynamicArray(const DynamicArray<T> &rhs)
{
deepCopy(rhs);
}
template <class T>
DynamicArray<T>& DynamicArray<T>::operator =(const DynamicArray<T>& rhs) {
if (this != &rhs) {
delete[] elements;
deepCopy(rhs);
}
return *this;
}
template<class T>
void DynamicArray<T>::deepCopy(const DynamicArray<T>& rhs)
{
size = rhs.size;
capacity = rhs.capacity;
elements = new T[capacity];
for (int i = 0; i < size; i++)
elements[i] = rhs.elements[i];
}
template<class T>
DynamicArray<T>::~DynamicArray()
{
delete[] elements;
}
template<class T>
void DynamicArray<T>::add(const T& value)
{
if (isCapacityAdjustmentNeeded())
setCapacity(size + 1);
T item = value;
elements[size++] = item;
}
template<class T>
void DynamicArray<T>::removeAt(int index)
{
if (!isIndexInRange(index))
throw std::out_of_range("Index out of range.");
for (int i = index; i < (size - 1); i++)
elements[i] = elements[i + 1];
size--;
if (isCapacityAdjustmentNeeded())
setCapacity(size + 1);
}
template<class T>
bool DynamicArray<T>::remove(const T& value)
{
int i = indexOf(value);
if (i >= 0) {
removeAt(i);
return true;
}
else
return false;
}
template<class T>
void DynamicArray<T>::insert(int index, const T& value)
{
if (!isIndexInRange(index))
throw std::out_of_range("Index out of range.");
if (isCapacityAdjustmentNeeded())
setCapacity(size + 1);
for (int i = size; i > index; i--)
elements[i] = elements[i - 1];
elements[index] = value;
size++;
}
template<class T>
int DynamicArray<T>::indexOf(const T& value) const
{
for (int i = 0; i < size; i++)
if (elements[i] == value)
return i;
return -1;
}
template<class T>
bool DynamicArray<T>::contains(const T& value) const
{
return indexOf(value) > -1;
}
template<class T>
int DynamicArray<T>::getSize() const
{
return size;
}
template<class T>
int DynamicArray<T>::getCapacity() const
{
return capacity;
}
template<class T>
bool DynamicArray<T>::operator==(DynamicArray<T> & rhs) const
{
if (this != &rhs) {
if (rhs.size != size)
return false;
for (int i = 0; i < size; i++)
if (rhs[i] != elements[i])
return false;
}
return true;
}
template<class T>
bool DynamicArray<T>::operator!=(DynamicArray<T>& rhs) const
{
return !(this == &rhs);
}
template<class T>
bool DynamicArray<T>::isCapacityAdjustmentNeeded() const
{
return !((size + 1) > MINIMUM_SIZE_ALLOWED*capacity && size < capacity);
}
template<class T>
bool DynamicArray<T>::isIndexInRange(int index) const
{
return (index >= 0 && index <= (size - 1));
}
template<class T>
void DynamicArray<T>::setCapacity(int minCapacity)
{
if (minCapacity < size)
throw std::logic_error("Capacity must be greater than current size.");
if (minCapacity >= 0)
{
int limit = 1;
while (limit <= minCapacity)
limit *= GROWTH_FACTOR;
T *tarray = new T[limit];
for (int i = 0; i < size; i++)
tarray[i] = elements[i];
delete[] elements;
elements = tarray;
capacity = limit;
}
}
template<class T>
T& DynamicArray<T>::operator[](int index)
{
if (!isIndexInRange(index))
throw std::out_of_range("Index out of range.");
return elements[index];
}
template<class T>
const T& DynamicArray<T>::operator[](int index) const
{
if (!isIndexInRange(index))
throw std::out_of_range("Index out of range.");
return elements[index];
}
template<class T>
void DynamicArray<T>::clear()
{
delete[] elements;
size = 0;
capacity = INITIAL_CAPACITY;
elements = new T[capacity];
}
template<class T>
bool DynamicArray<T>::isEmpty() const
{
return (size == 0);
}
}
Explanation / Answer
This might work.
Library.h
#pragma once
#include <iostream>
#include <string>
namespace cs20a {
using namespace std;
class Book
{
public:
Book();
Book(string author, string title, int copies = 1, int checkedOut = 0);
string getAuthor() const;
string getTitle() const;
void setAuthor(string author);
void setTitle(string title);
int getCopies() const;
int getCheckedOut() const;
void addCopy();
void deleteCopy();
void checkOut();
void checkIn();
friend ostream& operator << (ostream& outs, const Book& book);
private:
string author, title;
int copies, checkedOut;
};
}
Library.cpp
#include <stdexcept>
#include "Library.h"
namespace cs20a {
void Library::addBookToCollection(string author, string title){
Book book(author,title, copies, checkedOut);
myBooks[ ] = book;
NumberOfBooks++;
}
void Library::checkoutBook(std:: string author, std:: string title) throw(...)
{
Book book(author,title, copies, checkedOut);
int locationOfBook;
bool isBookFound = false;
for(int i = 0; i<NumberOfBooks; i++)
{
if(myBooks[i].getTitle() == book.getTitle() && myBooks[i].getAuthor() == book.getAuthor())
{
isBookFound = true;
locationOfBook = 1;
}
}
if(!isBookFound)
{
myBooks[locationOfBook].increaseNumberOfTimesCheckedOut();
}
else
{
throw BookNotFound();
}
}
ostream & operator<<(ostream & outs, const Library & library)
{
for (int i = 0; i < library.getTotalBooks(); i++)
outs << library.books[i] << endl;
return outs;
}
}
Book.h
#pragma once
#include <iostream>
#include <string>
namespace cs20a {
using namespace std;
class Book
{
public:
Book();
Book(string author, string title, int copies = 1, int checkedOut = 0);
string getAuthor() const;
string getTitle() const;
void setAuthor(string author);
void setTitle(string title);
int getCopies() const;
int getCheckedOut() const;
void addCopy();
void deleteCopy();
void checkOut();
void checkIn();
friend ostream& operator << (ostream& outs, const Book& book);
private:
string author, title;
int copies, checkedOut;
};
}
Book.cpp
#include <stdexcept>
#include "Book.h"
namespace cs20a {
Book::Book(string author, string title, int copies, int checkedOut)
: author(author), title(title), copies(copies), checkedOut(checkedOut)
{
my_Author = author;
my_Title = title;
my_copies = copies;
my_checkedout = checkedOut;
}
ostream & cs20a::operator<<(ostream & outs, const Book & book)
{
cout << book.title << ", by " << book.author << " Copies: "
<< book.copies << " Checked out: " << book.checkedOut;
return outs;
}
}
Librarydriver.cpp
#include <iostream>
#include "Library.h"
#include "Book.h"
using namespace std;
using namespace cs20a;
int main()
{
Library library;
try
{
cout << "--> Before Initial State." << endl;
library.addBook("Ernest Hemingway", "For Whom the Bell Tolls");
library.addBook("Ernest Hemingway", "For Whom the Bell Tolls");
library.addBook("John Steinbeck", "The Grapes of Wrath");
library.addBook("John Steinbeck", "The Grapes of Wrath");
library.addBook("John Steinbeck", "East of Eden");
library.addBook("Mark Twain", "Huckleberry Finn");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After Initial State." << endl << endl;
try
{
cout << "--> Before deleting Main Street and For Whom the Bell Tolls." << endl;
if (library.hasBook("Sinclair Lewis", "Main Street"))
library.deleteBook("Sinclair Lewis", "Main Street");
library.deleteBook("Ernest Hemingway", "For Whom the Bell Tolls");
library.deleteBook("Ernest Hemingway", "For Whom the Bell Tolls");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After deleting Main Street and For Whom the Bell Tolls." << endl << endl;
try
{
cout << "--> Before checking out For Whom the Bell Tolls and The Grapes of Wrath." << endl;
if (library.hasBook("Ernest Hemingway", "For Whom the Bell Tolls"))
library.checkOutBook("Ernest Hemingway", "For Whom the Bell Tolls");
if (library.hasBook("John Steinbeck", "The Grapes of Wrath"))
library.checkOutBook("John Steinbeck", "The Grapes of Wrath");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After checking out For Whom the Bell Tolls and The Grapes of Wrath." << endl << endl;
try
{
cout << "--> Before checking checking in For Whom the Bell Tolls." << endl;
library.checkInBook("Ernest Hemingway", "For Whom the Bell Tolls");
library.checkInBook("Ernest Hemingway", "For Whom the Bell Tolls");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After checking checking in For Whom the Bell Tolls." << endl << endl;
try
{
cout << "--> Before checking in The Grapes of Wrath." << endl;
library.checkInBook("John Steinbeck", "The Grapes of Wrath");
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After checking in The Grapes of Wrath." << endl << endl;
try
{
cout << "--> Before checking in Huckleberry Finn." << endl;
library.checkInBook("Mark Twain", "Huckleberry Finn");
cout << endl;
cout << library;
}
catch (const std::exception& e)
{
cout << "*** " << e.what() << " ***" << endl;
}
cout << "--> After checking in Huckleberry Finn." << endl << endl;
system("pause");
return 0;
}
Dynamicarray.h
#pragma once
#include <stdexcept>
namespace cs20a
{
const int INITIAL_CAPACITY = 2;
const int GROWTH_FACTOR = 2;
const double MINIMUM_SIZE_ALLOWED = 0.25;
template<class T>
class DynamicArray
{
public:
DynamicArray();
DynamicArray(int capacity);
DynamicArray(const DynamicArray<T> &rhs);
~DynamicArray();
void add(const T& value);
void removeAt(int index);
void insert(int index, const T& value);
bool remove(const T& value);
int indexOf(const T& value) const;
bool contains(const T& value) const;
void clear();
int getSize() const;
int getCapacity() const;
bool isEmpty() const;
DynamicArray<T>& operator =(const DynamicArray<T>& rhs);
T& operator[](int index);
const T& operator[](int index) const;
bool operator==(DynamicArray<T> & a) const;
bool operator!=(DynamicArray<T> & a) const;
private:
int size, capacity;
T *elements;
void deepCopy(const DynamicArray<T>& rhs);
void setCapacity(int newCapacity);
bool isCapacityAdjustmentNeeded() const;
bool isIndexInRange(int index) const;
};
template<class T>
DynamicArray<T>::DynamicArray() : size(0), capacity(INITIAL_CAPACITY)
{
elements = new T[capacity];
}
template<class T>
DynamicArray<T>::DynamicArray(int capacity) : size(0), capacity(capacity)
{
elements = new T[capacity];
}
template<class T>
DynamicArray<T>::DynamicArray(const DynamicArray<T> &rhs)
{
deepCopy(rhs);
}
template <class T>
DynamicArray<T>& DynamicArray<T>::operator =(const DynamicArray<T>& rhs) {
if (this != &rhs) {
delete[] elements;
deepCopy(rhs);
}
return *this;
}
template<class T>
void DynamicArray<T>::deepCopy(const DynamicArray<T>& rhs)
{
size = rhs.size;
capacity = rhs.capacity;
elements = new T[capacity];
for (int i = 0; i < size; i++)
elements[i] = rhs.elements[i];
}
template<class T>
DynamicArray<T>::~DynamicArray()
{
delete[] elements;
}
template<class T>
void DynamicArray<T>::add(const T& value)
{
if (isCapacityAdjustmentNeeded())
setCapacity(size + 1);
T item = value;
elements[size++] = item;
}
template<class T>
void DynamicArray<T>::removeAt(int index)
{
if (!isIndexInRange(index))
throw std::out_of_range("Index out of range.");
for (int i = index; i < (size - 1); i++)
elements[i] = elements[i + 1];
size--;
if (isCapacityAdjustmentNeeded())
setCapacity(size + 1);
}
template<class T>
bool DynamicArray<T>::remove(const T& value)
{
int i = indexOf(value);
if (i >= 0) {
removeAt(i);
return true;
}
else
return false;
}
template<class T>
void DynamicArray<T>::insert(int index, const T& value)
{
if (!isIndexInRange(index))
throw std::out_of_range("Index out of range.");
if (isCapacityAdjustmentNeeded())
setCapacity(size + 1);
for (int i = size; i > index; i--)
elements[i] = elements[i - 1];
elements[index] = value;
size++;
}
template<class T>
int DynamicArray<T>::indexOf(const T& value) const
{
for (int i = 0; i < size; i++)
if (elements[i] == value)
return i;
return -1;
}
template<class T>
bool DynamicArray<T>::contains(const T& value) const
{
return indexOf(value) > -1;
}
template<class T>
int DynamicArray<T>::getSize() const
{
return size;
}
template<class T>
int DynamicArray<T>::getCapacity() const
{
return capacity;
}
template<class T>
bool DynamicArray<T>::operator==(DynamicArray<T> & rhs) const
{
if (this != &rhs) {
if (rhs.size != size)
return false;
for (int i = 0; i < size; i++)
if (rhs[i] != elements[i])
return false;
}
return true;
}
template<class T>
bool DynamicArray<T>::operator!=(DynamicArray<T>& rhs) const
{
return !(this == &rhs);
}
template<class T>
bool DynamicArray<T>::isCapacityAdjustmentNeeded() const
{
return !((size + 1) > MINIMUM_SIZE_ALLOWED*capacity && size < capacity);
}
template<class T>
bool DynamicArray<T>::isIndexInRange(int index) const
{
return (index >= 0 && index <= (size - 1));
}
template<class T>
void DynamicArray<T>::setCapacity(int minCapacity)
{
if (minCapacity < size)
throw std::logic_error("Capacity must be greater than current size.");
if (minCapacity >= 0)
{
int limit = 1;
while (limit <= minCapacity)
limit *= GROWTH_FACTOR;
T *tarray = new T[limit];
for (int i = 0; i < size; i++)
tarray[i] = elements[i];
delete[] elements;
elements = tarray;
capacity = limit;
}
}
template<class T>
T& DynamicArray<T>::operator[](int index)
{
if (!isIndexInRange(index))
throw std::out_of_range("Index out of range.");
return elements[index];
}
template<class T>
const T& DynamicArray<T>::operator[](int index) const
{
if (!isIndexInRange(index))
throw std::out_of_range("Index out of range.");
return elements[index];
}
template<class T>
void DynamicArray<T>::clear()
{
delete[] elements;
size = 0;
capacity = INITIAL_CAPACITY;
elements = new T[capacity];
}
template<class T>
bool DynamicArray<T>::isEmpty() const
{
return (size == 0);
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.