Associated classes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John J

    Associated classes

    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_entr ies ();

    r2.display_entr ies ();

    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_entr y
    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_rac e 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::ostream;

    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_rac e (Yacht* y, int pl, string ti)

    {

    if (nEntries<MAX_E NTRIES)

    {

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

    entries[nEntries++] = e;

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

    }

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

    }

    //Find an entry object(s)

    void Race::display_e ntries (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[i]);

    }

    }

    //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[i];

    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[i]);

    }

    return out;

    }

    //Race.h

    #ifndef RACE_H

    #define RACE_H

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

    #include <string> // for string manipulation

    using std::ostream;

    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_entr y ()

    {

    //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::getCapta in (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






  • John Harrison

    #2
    Re: Associated classes


    "John J" <...@...> wrote in message
    news:5791454b0d 5d3a1e2799cb792 1c3ada0@news.te ranews.com...[color=blue]
    > 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,[/color]
    Race[color=blue]
    > 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[/color]
    of[color=blue]
    > white space, unfortunately this occurs when I cut and paste from my
    > compiler)
    >[/color]
    [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[i];
    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[i];
    if (e->getPlace() == 1)
    {
    out << *e;
    found_a_winner = true; // a winner has been found
    }
    }
    if (!found_a_winne r) // 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.


    Comment

    • John J

      #3
      Re: Associated classes

      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_entr y() which will be called from the Race::enter_rac e(). It's
      the code in Yacht::add_entr y that I don't know how to implement. Any help
      you can offer would be appreciated.

      Thanks


      Comment

      • John Harrison

        #4
        Re: Associated classes


        "John J" <...@...> wrote in message
        news:5736e9d285 1695e083d93d793 bd86464@news.te ranews.com...[color=blue]
        > Once again John, thanks for your help.
        >
        > You're right about having to get it exactly right. C++ is a very[/color]
        unforgiving[color=blue]
        > language, although I suppose that isn't a bad thing as it enforces correct
        > syntax.[/color]

        I was thinking more of the logical structure of your program rather than
        syntax. Although you are right there as well.
        [color=blue]
        > 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.[/color]

        It gets easier with practice.
        [color=blue]
        >
        > 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[/color]
        in[color=blue]
        > 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[/color]
        called[color=blue]
        > Yacht::add_entr y() which will be called from the Race::enter_rac e(). It's
        > the code in Yacht::add_entr y that I don't know how to implement. Any help
        > you can offer would be appreciated.[/color]

        Well you have a similar function in Race::enter_rac e, 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_rac e creates Entries using
        new, whereas Yacht::add_entr y will use the entry created in
        Race::enter_rac e. This means that Race::enter_rac e will have to pass a
        pointer to the newly created Entry to Yacht::add_entr y. Yacht::add_entr y
        should be a pretty small function, 3 - 5 lines at most.

        [color=blue]
        >
        > Thanks
        >
        >[/color]


        Comment

        Working...