Re: Seg Fault When Debugging
Actually, I am wondering if I was being "dumb". I was trying to view the stringstream in the watches window. And, I think that could have been causing it. On a side note, I am having issues with my Queue. For whatever reason when I call getPoints() on a customer who should be a RewardsCustomer, it calls the Customer getPoints() and returns 0.
Re: Seg Fault When Debugging
If you haven't fixed which functions are virtual and which aren't, that might happen.
Re: Seg Fault When Debugging
I am at work right now, and don't have my most up to date code, but I am 95% certain I fixed that.
Because Customer is the base class I put a virtual in front of the function:
virtual int earnedPoints()
Then for my derived classes RewardsCustomer and EliteCustomer I've got:
virtual int earnedPoints()
for both.
For this does the virtual just go in the .h file? Or do I need to carry it over to the .cpp file as well?
The functions are set up correctly too. So, then I am safe to assume that it isn't my queue getting mixed up? As it is now I only use Customer in my queue. Because RewardsCustomer is a Customer as well, I assumed that would be good, and what you are saying is exactly that correct? Thanks again.
Edit: Eh...looks like I made a mistake. I need the virtual only the base class. I have it for the derived classes as well.
Re: Seg Fault When Debugging
Putting virtual in the derived class shouldn't hurt anything, although you only need it in the base class.
Now, the fact that you're storing Customer objects directly in the queue may well be a problem. Polymorphism only works when you're using pointers and references; assigning a Derived object to a Base object will "slice off" the part of the object specific to the Derived class.
What you need to do is store a Customer pointer in the queue/stack. However, naturally this comes with a caveat: the thing it's pointing at will need to either exist elsewhere, or else will need to be allocated using new, which in turn means you need to make sure it gets deleted in every case.
The easiest way to make this change without a lot of extra debugging work is to store a smart pointer in the data structure rather than a raw pointer.
If you have access to TR1 or Boost, then the shared_ptr from one of those packages is a good option. However, if you don't.....in this particular case, the std::auto_ptr may be an acceptable option. You need to be careful with those because they have not-entirely-intuitive semantics. Just don't try to copy the auto_ptr object, and you should be fine.
Re: Seg Fault When Debugging
Quote:
Originally Posted by
Lindley
Putting virtual in the derived class shouldn't hurt anything, although you only need it in the base class.
Now, the fact that you're storing Customer objects directly in the queue may well be a problem. Polymorphism only works when you're using pointers and references; assigning a Derived object to a Base object will "slice off" the part of the object specific to the Derived class.
What you need to do is store a Customer pointer in the queue/stack. However, naturally this comes with a caveat: the thing it's pointing at will need to either exist elsewhere, or else will need to be allocated using new, which in turn means you need to make sure it gets deleted in every case.
The easiest way to make this change without a lot of extra debugging work is to store a smart pointer in the data structure rather than a raw pointer.
If you have access to TR1 or Boost, then the shared_ptr from one of those packages is a good option. However, if you don't.....in this particular case, the std::auto_ptr may be an acceptable option. You need to be careful with those because they have not-entirely-intuitive semantics. Just don't try to copy the auto_ptr object, and you should be fine.
I'm pretty sure there is a rule that says to NEVER use std::auto_ptr inside stl containers.
This is because to work correctly, the containers expect their elements to be assignable, which is not the case with auto_ptr. Your program will break in subtle and messy ways.
Apparently, this is so dangerous, that the stl took special measures to even prevent compiling containers of auto_ptr. How?
Quote:
The copy constructor and the copy assignment operator of auto_ptr take a reference to a non-const right hand side objects and the standard containers' insert() takes a reference to a const and hence auto_ptr cannot be used. It will just not allow you to create a copy of auto_ptr inside the vector (standard containers) members. That will cause you compilation errors on a compliant compiler. Nice solution..isnt it?
The solution I personally like is to create lists, deques or sets of objects (not vectors), and simply have them manage the lifetime of the pointed to objects.
EDIT: Whoops, apparently you never actually said to put the auto_ptr inside the vector. My bad. Still, auto_ptr were mostly meant for things simple pimpl implementation. For building objects on the heap rather than the stack. Not to be moved around that much. They are just plain too dangerous.
Re: Seg Fault When Debugging
I completely agree. However, the queue implementation in question here is based on a linked list; one assumes that a QueueNode will never be copied (and this can be easily enforced by declaring the cctor/operator= as private). And the stack implementation is based on an array, but due to the semantics of a stack, it still ought to be possible to use auto_ptr safely.
Re: Seg Fault When Debugging
So it seems my options are use a smart pointer or I try to overload the operators for Customer and RewardsCustomer.
Re: Seg Fault When Debugging
I'm not sure what overloading operators has to do with it. Smart pointers are just a convenience, really. You can use raw pointers if you want.
Re: Seg Fault When Debugging
I'll have to reread this. I guess I don't quite understand what is actually happening here. I was refering to the overloading to have both Customers and RewardsCustomers directly stored in the Queue, to try and avoid the issue. So, frontPtr->person could be a Customer and frontPtr->next->person could directly be a RewardsCustomer (I thought that's what I was doing).
Re: Seg Fault When Debugging
Yes, that's possible, but you'd need to store both in a Customer* (or some variety of smart_ptr<Customer>). Polymorphism only works through references and pointers, remember.
There actually is an alternative, now that I think about it, at least for the queue: You could templatize QueueNode, and then give all the various template types a common base class which is the type of the next and prev pointers. That might actually be simpler in some ways, but I'm guessing the additional concepts necessary to understand it would be a road block for you at this point.
Re: Seg Fault When Debugging
Aye. Well, I will work on the auto_ptr method. See if I can get that work. Seems like the most straightforward to understand.