I’m working on a project for school.
It simulates students buying soda from a vending machine.
There is a class called Card that is a member in the class Student.
That is,
Every student has a card, which makes sense.
class Student {
public:
Student( Office &cardOffice );
~Student();
bool action();
private:
Office* studentOffice; // stores cardoffice.
Card* card; // stores card
};
A student’s card is created via a call to the studentOffice.create() function. That function returns a card.
Card* Office::create( int id, int money ) {
Card* card = new Card();
card->id = id;
card->amount = money;
return card;
}
Students call a function in the class VendingMachine called action() to buy food. The buy function in VendingMachine returns a type enumeration from the Status enum in the VendingMachine class.
There is a prng, generating a random number from 0 – 9. The assignment says that there is a 1 in 10 chance of the student’s card being destroyed. And he/she will obtain a new one the next time student.action() is called.
VendingMachine::Status VendingMachine::buy(Card* &card)
{
if(prng(9) == 0) // generates number from 0-9
{
delete card;
}
return status;
}
Originally, I was thinking to check in the student’s action() routine to see if the card is NULL, (if it was deleted), and create a new one if that happens. However, I know the code gets to the delete card portion, but it fails when checking that the card is NULL. So that must mean the card is not null, which means the delete didn’t work.
But I also noticed that the card that is passed in is of type
Card* &card
I was then thinking of using a call with the “this” pointer as I know the student is what called this routine and “this” will point to the object that called it according to:
It points to the object for which the member function is called.
from http://msdn.microsoft.com/en-us/library/y0dddwwd(v=vs.80).aspx
However, if I do:
if(prng(9) == 0)
{
delete this->card;
}
it gives me this error when running my makefile:
error: class VendingMachine has no member named card
Which is true, it doesn’t. Is the compiler assuming that a VendingMachine will call this method? Because the student does.
-
Maybe I should add a student to every vending machine and delete the card from that member instead? I would strongly prefer not doing this, as there are multiple students and that would mean I need to store them all if they are assigned to this vending machine. Although, if it comes down to it, I could do it this way.
-
If the delete card happened, but the card is not NULL, what exactly went down when I deleted the card?
-
How would I go about deleting the card?
Thanks!
EDIT: After applying the changes, the code is now:
if(prng(9) == 0)
{
cout << "Destroying card" << endl;
delete card;
card = NULL;
cout << "Card Destroyed" << endl;
}
Unfortunately, I get a segfault and that is probably because I’m accessing a destroyed card that doesn’t exist. Because Destroying card and Card Destroyed is displayed,
But the cout I have in this call is not showing up:
if(card == NULL)
{
cout << "CARD DESTROYEDADJIWJDOQIODJWDIOJWQODWODIQODJWJOWDW" << endl;
card = studentOffice->create(id, 5);
}
So apparently the card is still not NULL? This is weird.
EDIT2: I think I know where the problem is, and why there’s a segfault. Working on it right now.
EDIT3: Solved by rearranging the order on the calls that used card when it was destroyed.
In method
buyyou should delete the pointer and set it toNULL(deletedoes not automatically set the pointer toNULL):That is the reason why the pointer is passed by reference (so you can assign
NULLto the original pointer and not a copy of it).Besides that,
this->carddoes not compile, sincecardbelongs to classStudent, not toVendingMachine. FromVendingMachine‘s perspective, it is just a parameter in methodbuy.