By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,864 Members | 1,242 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,864 IT Pros & Developers. It's quick & easy.

Beginner's problem: inheritence and vectors storing bookings

P: n/a
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.
Dec 13 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a

"Mike Jolley" <jo**********@tesco.netwrote in message
news:_f******************@newsfe1-gui.ntli.net...
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

Dec 14 '06 #2

P: n/a
Howard wrote:
"Mike Jolley" <jo**********@tesco.netwrote in message
news:_f******************@newsfe1-gui.ntli.net...
>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
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?
Dec 14 '06 #3

P: n/a
Mike Jolley wrote:
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 *

--
Tobias Gneist
Dec 14 '06 #4

P: n/a
Tobias Gneist wrote:
Mike Jolley wrote:
>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 *
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 :)
Dec 14 '06 #5

P: n/a
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,dat e );
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?
Dec 14 '06 #6

P: n/a

"Mike Jolley" <jo**********@tesco.netwrote in message
news:47*****************@newsfe6-win.ntli.net...
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,dat e );
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
Dec 14 '06 #7

P: n/a

"Howard" <al*****@hotmail.comwrote in message news:BE_fh.199416
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&".
can fix that by calling addBooking lke this: addBooking(*boatRec);


Dec 14 '06 #8

P: n/a
Howard wrote:
"Mike Jolley" <jo**********@tesco.netwrote in message
news:47*****************@newsfe6-win.ntli.net...
>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,da te );
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.
Dec 14 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.