object oriented – Library Management System OOP with c++( Part2 of a series )


I don’t know if this is acceptable, but I would love to thank the community for their advice concerning my previous post on this project

This is a beginner’s project.

Library management system aims to handle the basic housekeeping of a functional library, so far I have implemented the BookItem class and with advice from the community, also implemented a Date class( not with full funtionalities )

Librarian class though not completed yet is also functional…
I used a list to store the books in the library. I saw some post where vectors are suggested as the goto data structure, I feel list best suit this case, If vectors would be better I would appreciate if you highlight the reasons.

Note am a beginner and have no knowledge about C++ advanced topics yet.

Here is the code

Date.hh

#ifndef DATE_HH
#define DATE_HH
/*****************************************************************
 * Name: Date.hh
 * Author: Samuel Oseh
 * Purpose: Date class method-function prototype
 * ***************************************************************/
#include <iostream>
class Date {
    friend std::ostream &operator<<( std::ostream &, const Date & );
     private:
        /* data-member */
        unsigned int month;
        unsigned int day;
        unsigned int year;

        // utility function
        unsigned int checkDay( int ) const;

    public:
        static const unsigned int monthsPerYear = 12;

        // ctors
        Date() : Date( 1, 1, 1970 ){}
        Date( int m, int d, int y ) { setDate( m, d, y );}
        Date( int m ) : Date( m, 1, 1970 ){}
        Date( int m, int d ) : Date( m, d, 1970 ) {}
        
        // copy operations
        Date( const Date &d ) { *this = std::move(d); }
        Date &operator=( const Date &d ) { month = d.month; day = d.day; year = d.year; return *this; }

        /* method-functions */
        void setDate( int m, int d, int y );
        void setMonth( int m );
        void setDay( int d );
        void setYear( int y );
        unsigned int getMonth() const;
        unsigned int getDay() const;
        unsigned int getYear() const;       
        void nextDay();

        // dtor
        ~Date(){};
};

#endif

Date.cc

/*****************************************************************
 * Name: Date.cc
 * Author: Samuel Oseh
 * Purpose: Date class method-function definitions
 * ***************************************************************/
#include <iostream>
#include <stdexcept>
#include <array>
#include "Date.hh"

void Date::setDate( int m, int d, int y) {
    setMonth( m );
    setDay( d );
    setYear( y );
}

void Date::setDay( int d ) {
    day = checkDay( d );
}

void Date::setMonth( int m ) {
   if ( m >= 1 && m < 13 )
        month = m;
    else
      throw std::invalid_argument( "Month must be between 1-12" );
}

void Date::setYear( int y ) {
    if ( y >= 1970 )
        year = y;
    else
        throw std::invalid_argument( "year must be greater than 1969" );
}

void Date::nextDay() {
    day += 1;
    try {
        checkDay( day );
    } catch ( std::invalid_argument &e ) {
        month += 1;
        day = 1;
    }
    if ( month % 12 == 0 ) {
        year += 1;
        month = 1;
    }
}

std::ostream &operator<<( std::ostream &os, const Date &d ) {
    os << d.month << "/" << d.day << "/" << d.year << " ";

    return os;
} 

// utility function
unsigned int Date::checkDay( int testDay ) const {
    static const std::array < int, monthsPerYear + 1 > daysPerMonth = { 0,31,28,31,30,31,30,31,31,30,32,30,31};

    if ( testDay > 0 && testDay <= daysPerMonth( month ) )
        return testDay;
    
    if ( month == 2 && testDay == 29 && ( year % 400 == 0 || ( year % 4 == 0 && year % 100 != 0 ) ) )
        return testDay;
    throw std::invalid_argument( "Invalid day for current month and year" );
}

BookItem.hh

#ifndef BOOKITEM_HH
#define BOOKITEM_HH
/*****************************************************************
 * Name: BookItem.hh
 * Author: Samuel Oseh
 * Purpose: BookItem class method-function prototype
 * ***************************************************************/
#include <string>
#include "Date.hh"

enum class BookStatus : unsigned { RESERVED, AVAILABLE, UNAVAILABLE, REFERENCE, LOANED, NONE };
enum class BookType : unsigned { HARDCOVER, MAGAZINE, NEWSLETTER, AUDIO, JOURNAL, SOFTCOPY };

class BookItem {
    private:
        /* data-members */
        std::string title;
        std::string author;
        std::string category;
        Date pubDate;
        std::string isbn;
        BookStatus status;
        BookType type;
    public:
        // ctor
        BookItem() = default;
        BookItem( const std::string &title, const std::string &author, const std::string &cat, const Date &pubDate, 
                const std::string &isbn, const BookStatus status, const BookType type ); 

        // copy operations
        const BookItem& operator=( const BookItem &bookItem );
        BookItem( const BookItem &bookItem ) { *this = std::move(bookItem); }

        /* method-functions */
        void setStatus( BookStatus s ) { status = s; };
        void setType( BookType t ) { type = t;};
        std::string getStatus() const;
        std::string getType() const;
        std::string getTitle() const { return title; }
        std::string getAuthor() const { return author; }
        Date &getPubDate() { return pubDate; }
        void printPubDate() const { std::cout << pubDate; }
        std::string getIsbn() const { return isbn; }
        void setCategory( const std::string &c ) { category = c; }
        std::string getCategory() const { return category; };

        // dtor
        ~BookItem(){}
};
#endif

BookItem.cc

/*****************************************************************
 * Name: BookItem.cc
 * Author: Samuel Oseh
 * Purpose: BookItem class method-function definitions
 * ***************************************************************/
 #include <iostream>
#include "BookItem.hh"

BookItem::BookItem( const std::string &t, const std::string &a, const std::string &c, const Date &d, 
                const std::string &i, const BookStatus s, const BookType ty ) {
                    title = t, author = a, category = c, pubDate = d, isbn = i;
                    setStatus( s );
                    setType( ty );
}

const BookItem &BookItem::operator=( const BookItem &bookItem ) {
    title = bookItem.title;
    author = bookItem.author;
    category = bookItem.category;
    pubDate =  bookItem.pubDate;
    isbn = bookItem.isbn;
    status = bookItem.status;
    type = bookItem.type;

    return *this;
}

std::string BookItem::getStatus() const { 
    if ( status == BookStatus::AVAILABLE )
        return "AVAILABLE";
    else if ( status == BookStatus::REFERENCE )
        return "REFERENCE";
    else if ( status == BookStatus::UNAVAILABLE )
        return "UNAVAILABLE";
    else if ( status == BookStatus::LOANED )
        return "LOANED";
    else if ( status == BookStatus::RESERVED )
        return "RESERVED";
    else
        return "NONE";
} 

std::string BookItem::getType() const {
    if ( type == BookType::AUDIO )
        return "AUDIO";
    if ( type == BookType::HARDCOVER )
        return "HARDCOVER";
    if ( type == BookType::JOURNAL )
        return "JOURNAL";
    if ( type == BookType::MAGAZINE )
        return "MAGAZINE";
    if ( type == BookType::NEWSLETTER )
        return "NEWSLETTER";
    if ( type == BookType::SOFTCOPY )
        return "SOFTCOPY";
    else 
        return "NONE";
}

Librarian.hh

#ifndef LIBRARIAN_HH
#define LIBRARIAN_HH
/*****************************************************************
 * Name: Librarian.hh
 * Author: Samuel Oseh
 * Purpose: Librarian class method-function prototype
 * ***************************************************************/
#include <iostream>
#include <string>
#include "BookItem.hh"
#include <list>

class Librarian {
    private:
        /* data-member */
        std::string name;
        Date dateOfHire;
        std::list<BookItem> *books = new std::list<BookItem>;
    public:
        // ctor
        Librarian() = default;
        Librarian( const std::string &name, const Date &dateOfHire );

        /* basic method-functions */
        void setName( const std::string &name );
        void setDateOfHire( const Date &date );
        std::string getName() const { return name; };
        Date &getDateOfHire() { return dateOfHire; }
        void printDateOfHire() const { std::cout << dateOfHire; }

        /* core functionalities */
        void addBook( const BookItem &book );
        void auditLibrary() const;
        
        // dtor
        ~Librarian(){}
};

#endif

Librarian.cc

/*****************************************************************
 * Name: Librarian.cc
 * Author: Samuel Oseh
 * Purpose: Librarian class method-function definitions
 * ***************************************************************/

#include <iostream>
#include "Librarian.hh"

Librarian::Librarian( const std::string &n, const Date &d ) {
    name = n;
    dateOfHire = d;
}

void Librarian::setName( const std::string &n ) {
    name = n;
}

void Librarian::setDateOfHire( const Date &d) {
    dateOfHire = d;
}

void Librarian::addBook( const BookItem &book ) { 
    if ( books->empty() ) {
        books->push_front( book );
        return;
    }
    for ( auto bk = books->begin(); bk != books->end(); ++bk ) {
        if( book.getTitle() <= bk->getTitle() ) {
            books->insert(bk, book);
            return;
        }
    }
    books->push_back( book );
}

void Librarian::auditLibrary() const {
    std::cout << "Librarian: " << name << ", Date of hire: " << dateOfHire;
    std::cout << "nnBooks:";
    for ( auto bk = books->begin(); bk != books->end(); ++bk ) {
        std::cout << "nName of book: " << bk->getTitle();
        std::cout << "nAuthor of book: " << bk->getAuthor();
        std::cout << "nBook category: " << bk->getCategory();
        std::cout << "nPublication date: ";
        bk->printPubDate();
        std::cout << "nISBN number: " << bk->getIsbn();
        std::cout << "nStatus of book: " << bk->getStatus();
        std::cout << "nType of book: " << bk->getType();
        std::cout << "nn"; 
    }
}