Beginner's problem: inheritence and vectors storing bookings

M

Mike Jolley

Hello

First off, I'm a student so I'm pretty new to C++, and therefore I have
probably made a stupid mistake somewhere.
Anyway Ive been trying to fix this 5 hours straight now, so i need a
little assistance.

What I'm trying to do
I am using inheritance to make some bookings for a marina, which are:
Booking
|
__________________________________
| | |
narrowBoat motorBoat sailingBoat

These bookings are being stored in a vector in the bookingRecords
collection class:
private :
vector< booking > m_bookings;

I'm adding bookings like this:
void bookingRecords::addBooking(booking& v)
{
m_bookings.push_back( v ); //push to back of vector
}

Then iterating over them to run a method:
string bookingRecords::toString()
{
string retv("");
vector< booking >::iterator iter;
for (iter = m_bookings.begin(); iter !=m_bookings.end(); iter++)
{
retv+= iter->BtoString() + "\n";
}

return(retv);
}

The problem? When they get stored in this vector they lose their type
(e.g narrowBoat) and become a standard booking. I know this because when
I try to run a method (which is virtual in the booking class) it does
not run the correct method from one of the sub classes.

I did a bit of research and found a possible solution of using pointers
inside the vector instead of type booking, however I have not been able
to get this to work.

Any ideas on how to fix my problem? Am I totally in the wrong? I can
send my source on request if that helps.

Thanks for any assistance on this, it is much appreciated.
 
H

Howard

Mike Jolley said:
Hello

First off, I'm a student so I'm pretty new to C++, and therefore I have
probably made a stupid mistake somewhere.
Anyway Ive been trying to fix this 5 hours straight now, so i need a
little assistance.

What I'm trying to do
I am using inheritance to make some bookings for a marina, which are:
Booking
|
__________________________________
| | | narrowBoat motorBoat sailingBoat

These bookings are being stored in a vector in the bookingRecords
collection class:
private :
vector< booking > m_bookings;

I'm adding bookings like this:
void bookingRecords::addBooking(booking& v)
{
m_bookings.push_back( v ); //push to back of vector
}

Then iterating over them to run a method:
string bookingRecords::toString()
{
string retv("");
vector< booking >::iterator iter;
for (iter = m_bookings.begin(); iter !=m_bookings.end(); iter++)
{
retv+= iter->BtoString() + "\n";
}

return(retv);
}

The problem? When they get stored in this vector they lose their type (e.g
narrowBoat) and become a standard booking. I know this because when I try
to run a method (which is virtual in the booking class) it does not run
the correct method from one of the sub classes.

I did a bit of research and found a possible solution of using pointers
inside the vector instead of type booking, however I have not been able to
get this to work.

That's correct: you need to store pointers instead. But you don't show the
code where you've tried to do that.

The first thing is to define the vector to store pointers (with booking*
instead of booking as the data type). Then you can push_back &v, instead of
simply v, in addBooking. You'll also need to modify the code that accesses
the items so that it's using pointers.

Try again, and if you have a specific problem, post the code that you're
having problems with, and tell us exactly what problem you're having. Then
we can suggest a fix.

-Howard
 
M

Mike Jolley

Howard said:
That's correct: you need to store pointers instead. But you don't show the
code where you've tried to do that.

The first thing is to define the vector to store pointers (with booking*
instead of booking as the data type). Then you can push_back &v, instead of
simply v, in addBooking. You'll also need to modify the code that accesses
the items so that it's using pointers.

Try again, and if you have a specific problem, post the code that you're
having problems with, and tell us exactly what problem you're having. Then
we can suggest a fix.

-Howard

Thanks for the fast reply Howard, heres the bits i've changed:

The push back:
void bookingRecords::addBooking(booking& v)
{
m_bookings.push_back( &v ); //push to back of vector
}

The bookingRecord class:
private :
//vector< booking > m_bookings;
//vector that links to booking records
vector< booking* > m_bookings;

The iterator bit:
string bookingRecords::toString()
{
string retv("");
vector< booking* >::iterator iter;
for (iter = m_bookings.begin(); iter !=m_bookings.end(); iter++)
{
retv+= iter->BtoString() + "\n";
}

return(retv);
}

Now the error Im getting is that BtoString is undeclared, that is the
line I think im having problems with. Ive tried all sorts of variations
for example &iter-> *iter-> &iter. *iter. but i cannot find the code
to make it work.

Am i missing something?
 
T

Tobias Gneist

Mike said:
Now the error Im getting is that BtoString is undeclared, that is the
line I think im having problems with. Ive tried all sorts of variations
for example &iter-> *iter-> &iter. *iter. but i cannot find the code
to make it work.

Am i missing something?

Did you try the following?
(*iter)->BtoString()

-> binds stronger than *
 
M

Mike Jolley

Tobias said:
Did you try the following?
(*iter)->BtoString()

-> binds stronger than *

Cheers that fixed that error, its still not working so Ill spend some
time trying stuff out and if I stay stuck Ill post again later. Thanks
again :)
 
M

Mike Jolley

Right I'm having problem with loading from my file, the problem occurs
in the class method 'load()'

Heres an extract -
if ( boatType[0]=='M' )
{
booking* boatRec = new motorBoat(
customerName,boatName,boatLength,boatDraft,dur,date );
tok = strtok( NULL, "," );
motors = atoi(tok);
boatRec->setMotors(motors);
addBooking(boatRec);
counter++;
}

I get errors with both -
boatRec->setMotors(motors);
"class booking has no member named setMotors"
- and -
addBooking(boatRec);
"no matching function for call to `bookingRecords::addBooking(booking*&)"

Which is weird because setMotors DOES exist in the motorBoat sub class
and addBooking DOES exist in the recordBooking class (where this code is
inside).

Any ideas?
 
H

Howard

Mike Jolley said:
Right I'm having problem with loading from my file, the problem occurs in
the class method 'load()'

Heres an extract -
if ( boatType[0]=='M' )
{
booking* boatRec = new motorBoat(
customerName,boatName,boatLength,boatDraft,dur,date );
tok = strtok( NULL, "," );
motors = atoi(tok);
boatRec->setMotors(motors);
addBooking(boatRec);
counter++;
}

I get errors with both -
boatRec->setMotors(motors);
"class booking has no member named setMotors"
- and -
addBooking(boatRec);
"no matching function for call to `bookingRecords::addBooking(booking*&)"

Which is weird because setMotors DOES exist in the motorBoat sub class and
addBooking DOES exist in the recordBooking class (where this code is
inside).

Any ideas?

You've left out a lot of details, but I can guess:

The motorBoat class defines the function setMotors(), but it's not defined
in the booking class. You can solve this by adding an abstract virtual
function called setMotors() in the base class. Or, you could cast the
boatRec pointer as a motorBoat*. Or, you could define the boatRec pointer
as a motorBoat* to begin with. (I don't think you'll have to cast it to add
it to the vector, but if the compiler complains, then you can cast it
there.)

Or, since this appears to be initialization code, you could put the
setMotors call inside the constructor of the motorBoat object (and pass the
constructor anything it needs).

Or, you could create a virtual function (Initialize(), or something), which
is overridden in each subclass to do things like that code above.

The problem with the addBooking call is probably that you're passing
boatRec, which is a pointer, to addBooking, which expects a boatRec&. You
can fix that by calling addBooking lke this: addBooking(*boatRec);

-Howard
 
H

Howard

Howard said:
The problem with the addBooking call is probably that you're passing
boatRec, which is a pointer, to addBooking, which expects a boatRec&. You

correction: I meant to say "...expects a motorBoat&".
 
M

Mike Jolley

Howard said:
Mike Jolley said:
Right I'm having problem with loading from my file, the problem occurs in
the class method 'load()'

Heres an extract -
if ( boatType[0]=='M' )
{
booking* boatRec = new motorBoat(
customerName,boatName,boatLength,boatDraft,dur,date );
tok = strtok( NULL, "," );
motors = atoi(tok);
boatRec->setMotors(motors);
addBooking(boatRec);
counter++;
}

I get errors with both -
boatRec->setMotors(motors);
"class booking has no member named setMotors"
- and -
addBooking(boatRec);
"no matching function for call to `bookingRecords::addBooking(booking*&)"

Which is weird because setMotors DOES exist in the motorBoat sub class and
addBooking DOES exist in the recordBooking class (where this code is
inside).

Any ideas?

You've left out a lot of details, but I can guess:

The motorBoat class defines the function setMotors(), but it's not defined
in the booking class. You can solve this by adding an abstract virtual
function called setMotors() in the base class. Or, you could cast the
boatRec pointer as a motorBoat*. Or, you could define the boatRec pointer
as a motorBoat* to begin with. (I don't think you'll have to cast it to add
it to the vector, but if the compiler complains, then you can cast it
there.)

Or, since this appears to be initialization code, you could put the
setMotors call inside the constructor of the motorBoat object (and pass the
constructor anything it needs).

Or, you could create a virtual function (Initialize(), or something), which
is overridden in each subclass to do things like that code above.

The problem with the addBooking call is probably that you're passing
boatRec, which is a pointer, to addBooking, which expects a boatRec&. You
can fix that by calling addBooking lke this: addBooking(*boatRec);

-Howard

Thankyou so much! Hit the nail on the head. I used the motorBoat* and I
used the addBooking(*boatRec).

Thanks a million, Mike.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top