Hi,
I think first we need to start with the full text of the assignment, to see what is allowed, and what isn't.
Some things that jump out at me:
Why should a Publication know anything about a Person?
Classes should not have public data.
In my mind, a library
has a
Collection (an Inventory )of various things: say
books,
magazines,
videos. It also
has a membership (a
collection of) of
People. Members can borrow LenadableItems, which can be come Overdue
So that means a Library class, but only one instance of it. The class will have 4 std::vectors: one for LendableItems, another for Members, and another for borrowings, and Overdue. These are members of library because we don't want multiple objects of these things. There might be NonLendable items too. So far we have this outline:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
class LendableItems; // base class aka Publications
class Books : public LendableItems;
class Magazines : public LendableItems;
class Videos : public LendableItems;
class Library {
private:
std::vector<InventoryItem> Inventory;
std::vector<Person> Members;
std::vector<BorrowEvent> BorrowRegister;
std::vector<BorrowEvent> OverdueRegister
};
|
The
InventoryItem
class stores info about whether it is Lendable or not, it's
ISBN
and
BarCode
numbers and how copies of it there are.
Now
BorrowEvent
is a class of it's own, it stores the details of the event: which Item, who, when borrowed, when due, cost etc.
The
OverdueRegister
could be populated by going through the
BorrowRegister
to see which DueDate is prior to today's date.
Can you see from this outline how I have clearly organised things? I don't have a sparse 3D array. Try to do this each time you have a decent sized assignment, don't tear in and write 500 lines of code, then wonder why you wind up re doing the whole thing. Get out some Pen & Paper and draw diagrams of the classes and how they are related. If you can learn UML notation. Pictures are worth a thousand words. Class design is not as trivial as what people think it is.
Now for the code, in general:
There is too much code in main. Make more use of functions, it should be pretty obvious what can be a function. Especially though, the code in each case of the switch, make them a function call.
If data such as the cost and amount of time something can be borrowed for is stored within each item, then the act of borrowing (and returning) can become generic with some polymorphism. All we need to know is: What, Who, When. The functions inside each derived class do the heavy lifting. That way, the last big switch statement could be replaced with two small functions: one for borrowing, one for returning.
Some formatting ideas:
When one has a function with several arguments, put each one on it's own line. See how I named the arguments, and pass std::string by reference for now, see below about move semantics:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
Publication (const std::string& titleArg,
const std::string& authorArg,
const std::size_t numberArg, // better name BarCode ? Should be an unsigned type size_t, don't want negative values here
const std::size_t copiesArg
)
: // colon introduces member initialisation list, prevents initialising twice
title {titleArg},
author {authorArg} ,
number {numberArg} ,
copies {copiesArg}
{
// do validation here if required
}
|
There are other ways of doing this with move semantics, but I guess that is too advanced right now.
Also investigate putting code into separate *.hpp and *.cpp files
Good Luck !!