My list objects are being destroyed - c++

list<Book> *books = new list<Book>;
list<Book>::iterator pos;
void Administrator::addBook()
{
Book *newBook = new Book();
cout << "Would you like to enter a book?" << endl;
cin >> userInput;
cout << endl;
if (userInput == "yes")
{
cout << "What is the title of the book you want to enter?" << endl;
cin >> title;
cout << "What is the author of the book you want to enter?" << endl;
cin >> author;
cout << "What is the ISBN of the book you want to enter?" << endl;
cin >> ISBN;
cout << endl;
newBook->setTitle(title);
newBook->setAuthor(author);
newBook->setISBN(ISBN);
newBook->setAvailability(true);
books->push_back(*newBook);
}
}
*****************
I really need help with this, i have received a few answers today but none have helped me with this problem. This is my admin class. It creates books on the heap and stores them in an stl::list
void Guest::searchBook(Book* search)
{
string searchBook;
cout << "What book would you like to search for?" << endl;
cin >> searchBook;
printBookDetails();
}
This is my Guest class, what i would like to do here is to search through the list of books i created in my Administrator class but when it goes into the function printBookDetails, my list contains no elements, im assuming they've been destroyed.
Administrator* admin1 = new Administrator("jayfitz91", 24681357);
Guest* guest1 = new Guest("guest", 0000);
void main()
{
//Everything here works fine
admin1->addBook();
admin1->addBook();
admin1->makeAvailable();
admin1->printBookDetails();
//My list is destroyed at this point and it returns nothing
guest1->printBookDetails();
My Guest class inherits the printBookDetails from my Administrator class
All of the admin functions work but as soon as it gets to guest, the elements disappear.
Is there anyway i can get around this? The help would greatly be appreciated

Thanks to #OldProgrammer, i realised i had to return the list of books from my Admin class and pass it through as a parameter to my printBookDetails method in my guest class:
//Admin class
//Now returning a list
list<Book> Administrator::addBook()
{
Book *newBook = new Book();
cout << "Would you like to enter a book?" << endl;
cin >> userInput;
cout << endl;
if (userInput == "yes")
{
cout << "What is the title of the book you want to enter?" << endl;
cin >> title;
cout << "What is the author of the book you want to enter?" << endl;
cin >> author;
cout << "What is the ISBN of the book you want to enter?" << endl;
cin >> ISBN;
cout << endl;
newBook->setTitle(title);
newBook->setAuthor(author);
newBook->setISBN(ISBN);
newBook->setAvailability(true);
books->push_back(*newBook);
}
return *books;
}
//Guest class function
void Guest::printBookList(list<Book> *tempList)
{
pos = tempList->begin();
for (pos = tempList->begin(); pos != tempList->end(); ++pos)
{
cout << pos->getTitle() << "\n"
<< pos->getAuthor() << "\n"
<< pos->getISBN() << "\n"
<< pos->getAvailability() << "\n"
<< "******************************" << endl;
}
}
//Main class function
//Create a temporary variable for the list
list<Book> tempList;
//pass it through to the method
guest1->printBookList(&tempList);

First off, you don't have to dynamically create your list object.
list<Book> books = new list<Book>();
You do this because
you have less responsibility: you don't have to release the resources contained by books. It will automatically be released.
list is a stl container, which means it automatically handles dynamic allocations.
This is different if you use an dynamically allocated array...
I think your list is "gone" is because Guest and Administrator has two entirely different list.
To solve this issue, you should grant access to the book list that Administrator has to your Guest.
Or extract out the book list and store it in another class that allow access to the list to both Administrator and Guest.

Related

Creating new "dynamic" objects?

What is the best way of creating dynamic (not sure if this is the correct word) objects? For example, if I run the following:
Person man[10];
cout << "MENU" << endl;
cout << "1. Add a person to the list" << endl;
cout << "2. Delete a person from the list" << endl;
cout << "3. Change a person's information'" << endl;
cout << "4. Locate a person by ID number" << endl;
cout << "5. Locate a person by last name" << endl;
cout << "6. Print the list on the screen" << endl;
cout << "7. Load the list from a file" << endl;
cout << "8. Save the list to a file" << endl;
cout << "9. Exit the program" << endl;
cin >> a;
if (a == 1) {
if (i <= 10) {
Person man[i];
cout << "Please enter your last name: " ;
cin >> last;
man[i].setLastName(last);
i++;
cout << man[i].getLastName();
}
}
When I run this, I am allowed to enter my last name, but when I press ENTER the program stops running. What is the reason for this and is there a better way to create these objects "profiles"?
Thank you and I'm sorry if this is a stupid question.
The reason is your entire program only take one input cin >> a; and then check if its equal to 1. After the block the program has nothing left to do. So your program terminated.
If you want to edit all first name and last name of your 10 Person obj, you'd better create a loop to do that. For loop, you can google for / while.
Heres a example:
int i;
while(cin >> i)
{
if(i == 9)
return;
else if[....]
}
When you say dynamic, object allocation is via new operator. In your code, the array is already declared with 10 elements(static allocation). Hence in you code you are not performing dynamic allocation.
For dynamic allocation,add a function which can return you a new Person object. In this function create a object using new operator and return this object.
This way you add new objects dynamically.
Refer to new operator for more details on dynamic allocation.

How to remove a struct element from a vector?

I'm a newbie programmer and I'm working on a program that holds a registry of pets in a hotel (some silly exercise we saw in class, doesn't matter). I'm using vectors for holding the struct elements (pets). The code for the struct is this:
struct Pets{
string Name;
string Race;
string Owner;
int Tel;
}p;
And the function to ask for user input is this:
AddPet(vector<Pets> &vtnew)
{
Pets newpet;
cout << "Enter the pet's name: " << endl;
cin >> newpet.Name;
cout << "Enter the pet's race: " << endl;
cin >> newpet.Race;
cout << "Enter the owner's name: " << endl;
cin >> newpet.Owner;
cout << "Enter the owner's telephone number: " << endl;
cin >> newpet.Tel;
vtnew.push_back(newpet);
}
Ok, now I need to create a function to remove the pet by entering the name or something. Is there any way to do that?
A vector is an unsorted container so the simple solutions are really your only choice.
void RemovePet(std::vector<Pet> & pets, std::string name) {
pets.erase(
std::remove_if(pets.begin(), pets.end(), [&](Pet const & pet) {
return pet.Name == name;
}),
pets.end());
}
This is known as the Erase-remove idiom.
Note that this will remove all pets matching that name, not just one.

Adding to a struct from inside a loop in C++

I'm sorry if there are other threads that ask this question, but I unfortunately don't understand enough C++ yet to understand most of them.
I'm trying to use a loop to ask the user a series of questions, and then save those responses in a struct.
struct custOrder
{
char fruitOrdered[20];
int qty;
double orderPrice;
double totalPrice;
};
string choice;
cout << "Do you want to purchase fruit (yes/no)? ";
cin >> choice;
cout << endl;
char order;
double orderQTY;
for (choice; choice == "yes"; choice)
{
cout << "Which fruit would you like?" << endl << endl;
cin >> order;
cout << endl;
cout << "How many pounds would you like?";
cin >> orderQTY;
custOrder order = //if for example they respond "apples" i want the resulting variable to be custOrder.apples
{
order,
orderQTY,
order.price,
orderQTY * order.price
};
cout << "Do you want to purchase another fruit? ";
cin >> choice;
cout << endl;
}
cout << "Thanks for your business." << endl;
I know this is basic stuff, but I am completely lost.
You use something like:
custOrder thisOrder;
thisOrder.order = order;
thisOrder.orderQTY = orderQTY;
so its really quite easy - you just access the members of a struct variable as variableName.member. Not sure about your structure type definition, I would be using:
typedef struct custOrder....

Creating a list pointer that points to other objects

list<Book*> books;
list<Book>::iterator pos, last;
Book Administrator::addBook()
{
Book *newBook = new Book();
cout << "Would you like to enter a book?" << endl;
cin >> userInput;
cout << endl;
if (userInput == "yes")
{
cout << "What is the title of the book you want to enter?" << endl;
cin >> title;
cout << "What is the author of the book you want to enter?" << endl;
cin >> author;
cout << "What is the ISBN of the book you want to enter?" << endl;
cin >> ISBN;
cout << endl;
newBook->setTitle(title);
newBook->setAuthor(author);
newBook->setISBN(ISBN);
newBook->setAvailability(true);
books.push_back(newBook);
}
return *newBook;
}
void Administrator::printBookDetails()
{
books.begin()->setPrevBook(NULL);
for (pos = books.begin(); pos != books.end(); ++pos)
{
cout << pos->getTitle() << "\n"
<< pos->getAuthor() << "\n"
<< pos->getISBN() << "\n"
<< pos->getAvailability() << "\n"
<< "******************************" << endl;
if (pos != books.begin())
{
last->setNextBook(&*pos);
pos->setPrevBook(&*last);
}
last = pos;
}
books.back().setNextBook(NULL);
}
Can someone help me finish off this project please, these are my two functions addBook and printbookDetails . These are in my Admin class.
I would like the books i create on the heap to be stored in list< book*> books as i want to reference them in another class.
I've gotten a bit of help on here so far in regards to pointers and i know its something to do with me not linking the pointers to the correct objects.
My printBookDetails is giving me trouble, the first line books.begin()->setPrevBook(NULL); is saying i need a pointer-to-class type but when i put the -> i still have an error.
Book Guest::searchBook(Book* search)
{
string searchBook;
cout << "What book would you like to search for?" << endl;
cin >> searchBook;
printBookDetails();
}
What id like to do is use the searchBook function above in my Guest class to reference the books in the list at a later time but when i cannot seem to get my pointers right.
Can someone please put me on the right track.
for (pos = books.begin(); pos != books.end(); ++pos)
Here, pos is an iterator, over your list. Iterators are like pointers to list entries.
But each of your list entries is also a pointer to a book, not a book itself.
So, you need code like: (*pos)->getTitle() when trying to access member functions for those elements.

Creating objects on the heap through a class function

Book book;
list<Book>* books;
string title;
string author;
int ISBN;
Book* Administrator::addBook()
{
Book *newBook = new Book();
cout << "Would you like to enter a book?" << endl;
cin >> userInput;
cout << endl;
if (userInput == "yes")
{
cout << "What is the title of the book you want to enter?" << endl;
cin >> title;
cout << "What is the author of the book you want to enter?" << endl;
cin >> author;
cout << "What is the ISBN of the book you want to enter?" << endl;
cin >> ISBN;
cout << endl;
newBook->setTitle(title);
newBook->setAuthor(author);
newBook->setISBN(ISBN);
newBook->setAvailability(true);
books->push_back(*newBook);
}
return newBook;
}
Here im creating my book objects in my Administration class, the problem im having is when i try and access them from another class, its says they are not there.
I did a bit of reading and understand I've to allocate the objects to the heap using dynamic memory management, is there a way i can do this within my code?
Any help would greatly be appreciated.
Here's a simple way:
if (userInput == "yes")
{
Book *newBook = new Book(); // <-- allocates a Book object on the heap
cout << "What is the title of the book you want to enter?" << endl;
[...]
newBook->setTitle(title);
[...]
return *newBook;
}
you have to decide if you want to use the book that is in your class, or create a different book, or a heap copy of your book
if you want a different book you will need to use the new operator at the start
if you want to create a copy of your book on the heap:
return new Book(book)
Book* Administrator::addBook()
{
Book *bookOnHeap = new Book();
....
return bookOnHeap;
}