It's a good idea you declare the vector as a container of pointers to AbstractAccount because this way you can also hold pointers of classes derived from AbstractAccount (this is called upcasting), which as I understand is something that you want to do.
I cannot change the .h files of the SimpleBankingApplication or the AbstractAccount... |
Why is that?...
but I want to be able to store objects into the vector. How would this be done? |
Holding addresses of objects is fine as well, it's just more tricky to handle. When you choose to go this way you must make sure that the address you store on a vector always points at something
good every time you use it.
In your example you stored the address of a local variable in the vector and that could cause a problem. I realized that this wasn't really your intention and that you actually wanted to store the address of the newly dynamically allocated variable but, well you didn't do that... After the corrections I suggested it should work fine! Just remember to delete these things when you're done with them.
EDIT:
accountList[i]
returns a pointer to a base class object (AbstractAccount*) but you don't know if this is actually a derived object... Well, ok, you know it is because you made AbstractAccount pure virtual (which means you can't have instantiated objects of this type) and SavingsAccount is the only class derived from AbstractAccount. But what if you also had another class derived from AbstractAccount?... How would you know if it was a SavingsAccount or the other, since what you only have is a pointer to an AbstractAccount?... The answer is virtual functions! I gather you are familiar with them but I wanted you to see that this solution can't be used (directly) with these functions:
1 2
|
friend istream & operator>>(istream& inStream, SavingsAccount &accountToInput);
friend ostream & operator<<(ostream& outStream, const SavingsAccount accountToPrint);
|
as these functions are not memeber functions... What you can do though is declare & define a virtual function show() for your account classes and then do something like this:
1 2 3 4 5
|
//in your base class:
friend istream & operator>>(istream & inStream, AbstractAccount & accountToInput)
{accountToInput.show();}
friend ostream & operator<<(ostream & outStream, const AbstractAccount & accountToPrint)
{accountToPrint.show();}
|
1 2 3
|
//in your derived class:
friend ostream & operator<<(ostream& outStream, const SavingsAccount & accountToPrint)
{accountToPrint.show();}
|
Then you can use it like
cout << *(accountList[i]) << endl;
EDIT: I reworked a bit the solution I suggested with show() and ostream, fixed a
huge typo hahaha and add the following:
You can also do something like the above for input! Declare & define a virtual function set() that handles input of accounts and then add the following lines:
1 2 3
|
//in your base class:
friend istream & operator>>(istream & inStream, AbstractAccount & accountToInput)
{accountToInput.set();}
|
1 2 3
|
//in your derived class:
friend istream & operator>>(istream & inStream, SavingsAccount & accountToInput)
{accountToInput.set();}
|
Then you can use operator >> for input without caring whether the target object is a base or derived one.