heres the code
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <list>
using namespace std;
class Author {
public:
Author() = default;
~Author() {
delete[] _IDs;
_IDs = nullptr;
}
Author(const char* Name, const char* BirthDate, const int ID)
: _name(Name)
, _birthdate(BirthDate)
, _ID(ID)
{
for (int i = 0; i < _size; i++) {
if (ID == _IDs[i]) {
delete[] _IDs;
_IDs = nullptr;
throw new std::invalid_argument("ID Must be UNIQUE;");
}
}
check_alloc_ID_size();
_IDs[_size++] = ID;
}
Author(const Author& other)
: _name(other._name)
, _birthdate(other._birthdate)
, _ID(other._ID)
{}
public:
const char* GetBD() const { return _birthdate; }
const char* GetName() const { return _name; }
const int GetID() const { return _ID; }
private:
const char* _name;
const char* _birthdate;
const int _ID;
static int* _IDs;
static int _size;
static int _alloc_size;
private:
void check_alloc_ID_size() {
if (_size == _alloc_size) {
int* temp = _IDs;
_alloc_size *= 2;
_IDs = new int[_alloc_size];
for (int i = 0; i < _size; i++) {
_IDs[i] = temp[i];
}
delete[] temp;
}
}
};
int* Author::_IDs = new int[1];
int Author::_size = 0;
int Author::_alloc_size = 1;
class Book {
public:
Book(const char* title, const char* isbn, const int year, const Author& author)
: _title(title)
, _isbn(isbn)
, _year(year)
, _author(author)
{}
const char* GetTitle() const { return _title; }
const char* GetIsbn() const { return _isbn; }
const int GetYear() const { return _year; }
const Author& GetAuthor() const { return _author; }
void PrintBookInfo() {
printf("%s\n%s\n%d\n", GetTitle(), GetIsbn(), GetYear());
}
bool operator==(const Book& other) const {
return _isbn == other._isbn;
}
private:
const char* _title;
const char* _isbn;
const int _year;
const Author& _author;
};
class Patron {
public:
Patron() {}
bool operator==(const Patron& other) const {
return _libID == other._libID;
}
private:
const char* _name;
const char* _libID;
vector<Book> _checked;
};
class Library {
public:
Library()
{}
void AddBook(const Book& book) {
_books.push_back(make_pair(book, 1));
}
void RemoveBook(const Book& book) {
for (auto it = _books.begin(); it != _books.end(); ++it) {
if ((*it).first == static_cast<const Book&>(book)) {
_books.erase(it);
break;
}
}
}
void AddPatron(const Patron& patron) {
_patrons.push_back(patron);
}
void RemovePatron(const Patron& patron) {
for (auto it = _patrons.begin(); it != _patrons.end(); ++it) {
if (*it == patron) {
_patrons.erase(it);
break;
}
}
}
private:
vector<pair<Book, int>> _books;
vector<Patron> _patrons;
vector<Book> _checked_out_books;
vector<Book> _available_books;
};
Now the error is in the RemoveBook() function, and it pertains to an operator not being overloaded. I triet multiple solutions and even chat GPT couldn't figure it out. IF you aren't SURE it works, I probably already tried it. Any thanks greatly welcome!
It says to add more details. At first I was adding operator overloads in the Book class, then realised that the _books if in the library class. Im comparing Pair<> here so I'm not sure how the operator should go. Like I said I spent 3 hours with chatGPT giving me the wrong answers.
The iterator continuation doesn't matter like GPT suggests, you can just break out of the code, even though I tried that too.
Here is the working code
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <list>
using namespace std;
class Author {
public:
Author() = default;
~Author() {
delete[] _IDs;
_IDs = nullptr;
}
Author(const char* Name, const char* BirthDate, const int ID)
: _name(Name)
, _birthdate(BirthDate)
, _ID(ID)
{
for (int i = 0; i < _size; i++) {
if (ID == _IDs[i]) {
delete[] _IDs;
_IDs = nullptr;
throw new std::invalid_argument("ID Must be UNIQUE;");
}
}
check_alloc_ID_size();
_IDs[_size++] = ID;
}
Author(const Author& other)
: _name(other._name)
, _birthdate(other._birthdate)
, _ID(other._ID)
{}
public:
const char* GetBD() const { return _birthdate; }
const char* GetName() const { return _name; }
const int GetID() const { return _ID; }
private:
const char* _name;
const char* _birthdate;
int _ID;
static int* _IDs;
static int _size;
static int _alloc_size;
private:
void check_alloc_ID_size() {
if (_size == _alloc_size) {
int* temp = _IDs;
_alloc_size *= 2;
_IDs = new int[_alloc_size];
for (int i = 0; i < _size; i++) {
_IDs[i] = temp[i];
}
delete[] temp;
}
}
};
int* Author::_IDs = new int[1];
int Author::_size = 0;
int Author::_alloc_size = 1;
class Book {
public:
Book(const char* title, const char* isbn, const int year, const Author& author)
: _title(title)
, _isbn(isbn)
, _year(year)
, _author(author)
{}
const char* GetTitle() const { return _title; }
const char* GetIsbn() const { return _isbn; }
const int GetYear() const { return _year; }
const Author& GetAuthor() const { return _author; }
void PrintBookInfo() {
printf("%s\n%s\n%d\n", GetTitle(), GetIsbn(), GetYear());
}
bool operator==(const Book& other) const {
return _isbn == other._isbn;
}
private:
const char* _title;
const char* _isbn;
int _year = 9;
Author _author;
};
class Patron {
public:
Patron() {}
bool operator==(const Patron& other) const {
return _libID == other._libID;
}
private:
const char* _name;
const char* _libID;
vector<Book> _checked;
};
class Library {
public:
Library()
{}
void AddBook(const Book& book) {
_books.push_back(make_pair(book, 1));
}
void RemoveBook(const Book& book) {
for (auto it = _books.begin(); it != _books.end(); ++it) {
if ((*it).first == static_cast<const Book&>(book)) {
_books.erase(it);
break;
}
}
}
void AddPatron(const Patron& patron) {
_patrons.push_back(patron);
}
void RemovePatron(const Patron& patron) {
for (auto it = _patrons.begin(); it != _patrons.end(); ++it) {
if (*it == patron) {
_patrons.erase(it);
break;
}
}
}
private:
vector<pair<Book, int>> _books;
vector<Patron> _patrons;
vector<Book> _checked_out_books;
vector<Book> _available_books;
};
The problem is that _books.erase() performs a std::move operation however Book can not provide a default move constructor because it has a const reference member const Author& _author
which needs to be initialized on construction. Consequently you'd have to provide an Author& in the move constructer which you can't do because it's being called internally by _books.erase(). So you need the Book class to hold a copy of it.
For this solution to work you also need to make _ID
in the Author class non const otherwise Author can't provide a default constructor which is necessary for the std::move.
And a little side note return _isbn == other._isbn
does not actually compare the values of _isbn
and other._isbn
but rather if they are the same pointer, which they will never be since Library constructs it's own books. To compare the actual values of _isbn
and other._isbn
use:
bool operator==(const Book& other) const {
return strcmp(_isbn, other._isbn) == 0;
}