Associated classes

J

John J

I requested help with some code in a previous thread, as requested in the
feedback, below are the .cpp and .h files for all three classes (Entry, Race
and Yacht). The three classes are all ossociated through pointers. Objects
are created and called in a main as follows: (I apologise for the excess of
white space, unfortunately this occurs when I cut and paste from my
compiler)

Race r1(1, "23/12/03");

Race r2(2, "24/12/03");

Yacht y1("The Bounty", "William Bligh");

Yacht y2("The Hilda", "Some bloke");

Yacht y3("The Mary Celeste", "Benjamin Briggs");

Yacht y4("Speedy", "Some other bloke");


r1.enter_race (&y1,3, "22:30");

r1.enter_race (&y2,2, "22:00");

r1.enter_race (&y3,1, "21:00");

r2.enter_race (&y4,1, "15:00");

cout << r1 << endl;

cout << r2 << endl;


r1.display_entries ();

r2.display_entries ();

r1.winner ();



The classes seem to compile and link correctly; however, the Race::winner
function does not work and I'm not sure on how to code the Yacht::add_entry
function, comments of what this should do are in the body of the add_entry
function, this also needs to be called from the Race::enter_race function,
as commented within this function.

I realise my solution below could be refined somewhat; however, I'm still
very much learning and would greatly appreciate help on getting this project
to work.



Thanks



//Entry.cpp

#include <iostream>

#include <string>

#include "Entry.h"

#include "Race.h"

#include "Yacht.h"

using namespace std;

//Construct an Entry

Entry::Entry (Race* r, Yacht* y, int pl, string ti)

{

which = r;

what = y;

place = pl;

time = ti;

}



//Access functions

int Entry::getPlace () const

{

return place;

}

string Entry::getTime () const

{

return time;

}

Race* Entry::getRace () const

{

return which;

}

Yacht* Entry::getYacht () const

{

return what;

}

//Overload of operator<< for output of an Entry

ostream& operator<< (ostream& out, const Entry& e)

{

Yacht* y = e.what;

Race* r = e.which;

out << endl << "Yacht : " << *y << endl

<< "Race : " ; r->Show();

out << "Finish Place : " << e.place << endl

<< "Finish Time : " << e.time << endl << endl;


return out;

}

//Entry.h

#ifndef ENTRY_H

#define ENTRY_H

#include <iostream> // for standard i/o

#include <string> // for string manipulation

using std::eek:stream;

using std::string;

class Yacht;

class Race;

//Details of race entries

class Entry

{

friend ostream& operator<< (ostream&, const Entry&);

public:

//constructor

Entry (Race* r=NULL, Yacht* y=NULL, int pl=0, string ti="");

//access functions

int getPlace () const; //Yacht placing

string getTime () const; //Yacht finish time

Race* getRace () const; //Related race object

Yacht* getYacht () const; //Related yacht object



private:

//Attributes to implement the relationship

Race* which; //Which race

Yacht* what; //What yacht

//Attributes of the association

int place;

string time;


};

ostream& operator<< (ostream&, const Entry&);

#endif

//Race.cpp

#include <string>

#include "Race.h"

#include "Entry.h"

#include "Yacht.h"

using namespace std;

//Construct a race

Race::Race (int n, string d)

{

number = n;

date = d;

nEntries = 0;

for (int j=0; j<MAX_ENTRIES; j++)

entries[j] = NULL;

}

//Enter a race

void Race::enter_race (Yacht* y, int pl, string ti)

{

if (nEntries<MAX_ENTRIES)

{

Entry* e = new Entry (this,y,pl,ti);

entries[nEntries++] = e;

//y->add_entry; //need to call the Yacht::add_entry function here

}

else cout << "Too many entries" << endl;

}

//Find an entry object(s)

void Race::display_entries (ostream& out) const

{

if (nEntries == 0)

out << "No entries" << endl;

else

{

cout << "Details of Yachts entered into the requested race:" <<endl << endl;

for (int i=0; i<nEntries; i++)

out << *(entries);

}

}

//Find the winner

void Race::winner (ostream& out) const

{

//int i;

Entry* e = NULL;

if (nEntries == 0)

{

out << "No entries" << endl;

}

else

{

for (int i=0; i<nEntries; i++)

{

e = entries;

if (e)

if (e->getPlace() == 1)

{

out << e;

}

else

{

out << "No winner was found in this race" << endl;

}

}

}

}



//Access functions

int Race::getNumber (void) const

{

return number;

}

string Race::getDate (void) const

{

return date;

}

//Output functions

//Print Race info

void Race::Show (ostream& out) const

{

out << "Race Number : " << number << endl

<< "Race Date : " << date << endl;

}

ostream& operator<< (ostream& out, const Race& r)

{

r.Show (out);

if (r.nEntries == 0)

out << "No entries" << endl;

else

{

for (int i=0; i<r.nEntries; i++)

out << *(r.entries);

}

return out;

}

//Race.h

#ifndef RACE_H

#define RACE_H

#include <iostream> // for standard i/o

#include <string> // for string manipulation

using std::eek:stream;

using std::cout;

#include "Entry.h"

#include "Yacht.h"

const int MAX_ENTRIES = 20;

//Details of races

class Race

{

friend ostream& operator<< (ostream&, const Race&);

public:


//constructor

Race ( int n=0, string d="");

void enter_race (Yacht*,int, string);

void Show (ostream& out=cout) const;

void display_entries (ostream& out=cout) const;

void winner (ostream& out=cout) const;

//member function prototypes

int getNumber() const;

string getDate() const;

private:

//Attributes of yachts

int number;

string date;

//Attributes for association

Entry* entries[MAX_ENTRIES];

int nEntries;

};

ostream& operator<< (ostream&, const Race&);

#endif



//Yacht.cpp

#include <iostream>

#include <string>

#include "Yacht.h"

using namespace std;

//Construct a yacht

Yacht::Yacht (string n, string c)

{

name = n;

captain = c;

}

//Enter a race

void Yacht::add_entry ()

{

//Add_entry just needs to be given a pointer to the

//just-created new entry as its sole argument, and

//it should just store that pointer in the next unused

//location in an array of pointers to entries (mirroring

//the array of pointers to entries in the Race class).

//I have not yet declared the array of pointers in the

//Yacht class - it needs to be added and I'm not sure on

//how to do this correctly

}

//Access functions

string Yacht::getName (void) const

{

return name;

}

string Yacht::getCaptain (void) const

{

return captain;

}

//Overload of operator<< for output of a yacht

ostream& operator<< (ostream& out, const Yacht& y)

{

out << y.name << " (Captain: " << y.captain << ")";

return out;

}

//Yacht.h

#ifndef YACHT_H

#define YACHT_H

#include <iostream> // for standard i/o

#include <string> // for string manipulation

#include "Entry.h"

#include "Race.h"

using namespace std;

//Details of yachts

class Yacht

{

friend ostream& operator<< (ostream&, const Yacht&);

void add_entry ();

public:

//constructor

Yacht (string n="", string c="");

//member function prototypes

string getName() const;

string getCaptain() const;



private:

//Attributes of yachts

string name;

string captain;


};

ostream& operator<< (ostream&, const Yacht&);

#endif
 
J

John Harrison

John J said:
I requested help with some code in a previous thread, as requested in the
feedback, below are the .cpp and .h files for all three classes (Entry, Race
and Yacht). The three classes are all ossociated through pointers. Objects
are created and called in a main as follows: (I apologise for the excess of
white space, unfortunately this occurs when I cut and paste from my
compiler)
[snip]

//Find the winner
void Race::winner (ostream& out) const
{
Entry* e = NULL;
if (nEntries == 0)
{
out << "No entries" << endl;
}
else
{
for (int i=0; i<nEntries; i++)
{
e = entries;
if (e)
if (e->getPlace() == 1)
{
out << e;
}
else
{
out << "No winner was found in this race" << endl;
}
}
}
}

OK look at the above function. There are two things wrong with it. One
simple problem is this

out << e;

You are obviously trying to print out the winning yacht, but e is a pointer.
What you want is this

out << *e;

The other problem is rather more serious. You obviously want to print out
"No winner" if none of the yachts are winners, but instead you print out "No
Winner" for each of the yachts that is not a winner.

What you want is something like this

bool found_a_winner = false; // no winner found yet
for (int i=0; i<nEntries; i++)
{
e = entries;
if (e->getPlace() == 1)
{
out << *e;
found_a_winner = true; // a winner has been found
}
}
if (!found_a_winner) // did we find a winner?
out << "No winner was found in this race" << endl;

The thing about programming is that you have to get it exactly right. Its
very easy to put together a few loops and statements that are roughly
correct and think you've got it right. Next time you face a problem like
this try and trace though the code in your head or better still on a piece
of paper. And when you do this, act really stupid, as if you don't know at
all what your code is *meant* to do, just look at what it actually does.
That is how the computer is looking at your code.

john

PS A tip, when posting code, cut and paste it into a notepad file first, and
then into Outlook Express, that should cure the indentation and line spacing
problems.
 
J

John J

Once again John, thanks for your help.

You're right about having to get it exactly right. C++ is a very unforgiving
language, although I suppose that isn't a bad thing as it enforces correct
syntax. I'm looking forward to the day it all clicks in my mind and I don't
have to struggle for hours on end on a simple function.

The next step for this project is to include a display_races() (details of
the races a yacht participated in) and best_result () (to determine the
best result of a yacht in all the races). Both of these functions will go in
the Yacht class. I don't think I'll have a problem with these functions as
they are similar to two of the functions in the Race class; however, to
enable this to work correctly I must create a pointer to the just created
new entry. I'm not sure on how to do this. I intend to use a function called
Yacht::add_entry() which will be called from the Race::enter_race(). It's
the code in Yacht::add_entry that I don't know how to implement. Any help
you can offer would be appreciated.

Thanks
 
J

John Harrison

John J said:
Once again John, thanks for your help.

You're right about having to get it exactly right. C++ is a very unforgiving
language, although I suppose that isn't a bad thing as it enforces correct
syntax.

I was thinking more of the logical structure of your program rather than
syntax. Although you are right there as well.
I'm looking forward to the day it all clicks in my mind and I don't
have to struggle for hours on end on a simple function.

It gets easier with practice.
The next step for this project is to include a display_races() (details of
the races a yacht participated in) and best_result () (to determine the
best result of a yacht in all the races). Both of these functions will go in
the Yacht class. I don't think I'll have a problem with these functions as
they are similar to two of the functions in the Race class; however, to
enable this to work correctly I must create a pointer to the just created
new entry. I'm not sure on how to do this. I intend to use a function called
Yacht::add_entry() which will be called from the Race::enter_race(). It's
the code in Yacht::add_entry that I don't know how to implement. Any help
you can offer would be appreciated.

Well you have a similar function in Race::enter_race, it adds entries to an
array of Entry pointers held in the Race object. You'll need something
similar to add entries to an array of Entry pointers held in the Yacht
object. The only difference is the Race::enter_race creates Entries using
new, whereas Yacht::add_entry will use the entry created in
Race::enter_race. This means that Race::enter_race will have to pass a
pointer to the newly created Entry to Yacht::add_entry. Yacht::add_entry
should be a pretty small function, 3 - 5 lines at most.
 

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

Similar Threads

Unexpected Result 8
Class search function 1
Search function 3
Search function 0
Class problem 5
Chatbot 0
Calling a function in another class 2
Why doesn't implicit conversion work with wide ostream? 4

Members online

No members online now.

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top