C++ Interleaved classes Question

Hello all,

I am doing this assignment and I encounter an error.  Below is my code:

#include <string>
#include <iostream>
#include <vector>
#include <list>

using namespace std;

class Toast;
class SmartTurkey;
class Turkey;
class Person;

// To init.
class Date {
    int month;
    int day;
    int year;

public:
    //Date(): month(0), day(0), year(0) {};
    Date();
    Date( int m, int d, int y );

    friend ostream& operator<<( ostream& os, const Date* d );
}; // class Date {}


class DinnerParty {
    static const float ApplePi = 3.14;
    Date partyDate;
    Toast* beverage;
    SmartTurkey *courses;
    vector<Person*> gobblers;
    int storage;

public:
    DinnerParty();
    DinnerParty( Date p, Toast* b, SmartTurkey* c, int temp, vector<Person*> g );
   
    DinnerParty( const DinnerParty& other);
    DinnerParty& operator=( const DinnerParty& other);
    friend ostream& operator<<( ostream& os, const DinnerParty& dp );
    ~DinnerParty();
}; // class DinnerParty {}


class Person {
    string name;
    vector<Person*> friends;
    Toast* favoriteDrink;

public:
    Person();
    Person( string n, vector<Person*> f, Toast* fd );
    Person( string n, Toast* fd);
    Person( string n);
   
    Person& operator=( const Person& other);
    Person( const Person& other);
    friend ostream& operator<<( ostream& os, const Person& p );
    ~Person();
}; // class Person {}


class SmartTurkey {
    string stuffing;
    Turkey* roasted;

public:
      
    SmartTurkey();
    SmartTurkey(string makeTemp, Turkey* makeTemp1);
   
    SmartTurkey& operator=(const SmartTurkey& other);
    SmartTurkey(const SmartTurkey& other);
   
    friend ostream& operator<<( ostream& os, const SmartTurkey& p );
    ~SmartTurkey();
}; // class SmartTurkey {}


class Toast {
    string beverageName;
    int year;
      Person proposer;

public:
    Toast();
    Toast( string bn, int y, Person p );
   
    friend ostream& operator<<( ostream& os, const Toast& t );
}; // class Toast {}


class Turkey {
    string name;
    int age;
    Person owner;

public:
    Turkey();
    Turkey( string n, int a, Person o );
   
    friend ostream& operator<<( ostream& os, const Turkey& t );
}; // class Turkey {}

/* Date */

Date::Date() :
month(0), day(0), year(0) {}

Date::Date( int m, int d, int y ): month(m), day(d), year(y) {}

/* Dinner Party */
DinnerParty::DinnerParty() :
partyDate(Date(0,0,0)),beverage(0), courses(0), storage(0) {}

DinnerParty::DinnerParty( Date p, Toast* b, SmartTurkey *c, int temp, vector<Person*> g):

partyDate(p), storage(temp),gobblers(g)
{

if (b == 0){
  beverage = 0;
}
else{
  beverage = new Toast(*b);
}

if (temp != 0)
{
  courses = new SmartTurkey[temp];
  for (int i = 0; i < temp; i++)
    courses[i] = c[i];
}
else
  courses = 0;
}

// copy constructor:
DinnerParty::DinnerParty( const DinnerParty& other) :
  partyDate(other.partyDate), beverage(other.beverage), storage(other.storage), gobblers(other.gobblers)
{
  if (other.storage != 0)
  {
    courses = new SmartTurkey[storage];
    for (int i = 0; i<storage; i++)
      courses[i] = other.courses[i];
  }
  else
    courses = 0;
}

//Copy assignment operator:
DinnerParty& DinnerParty::operator=(const DinnerParty& other)
{
  if (this == &other) return *this;
 
  partyDate = other.partyDate;
  beverage = other.beverage;
  storage = other.storage;
  gobblers = other.gobblers;

  if (this->courses != 0)
    delete[] courses;
   
  if (other.courses != 0)
    for (int i = 0; i<storage; i++)
      this->courses[i] = other.courses[i];
  else
    courses = 0;
   
  return *this;
 
}
// Destructor:
DinnerParty::~DinnerParty()
{
  if (beverage != 0)
    delete beverage;
}

/* Person */
Person::Person()
{
favoriteDrink = 0;
}

Person::Person( string n, vector<Person*> f, Toast* fd ) :
  name(n),  
  friends(f)
{
  if ( fd == 0) favoriteDrink = 0;
    else favoriteDrink = new Toast(*fd);
}

Person::Person( string n, Toast* fd):
  name(n)
{
  if (fd == 0)
    favoriteDrink = 0;
  else
    favoriteDrink = new Toast(*fd);
}

Person::Person( string n) :
  name(n)
  {
    favoriteDrink = 0;
  }


// Copy constructor:
Person::Person( const Person& other) :  
  name(other.name),friends(other.friends)
{
  if (other.favoriteDrink != 0)
    favoriteDrink = new Toast(*(other.favoriteDrink));
  else
    favoriteDrink = 0;

}
 
// Copy assignment:
Person& Person::operator=( const Person& other)
{
  if (this == &other) return *this;
 
  name = other.name;
  friends = other.friends;
 
  if (this->favoriteDrink != 0)
    delete favoriteDrink;
   
  if (other.favoriteDrink != 0)
    favoriteDrink = new Toast(*other.favoriteDrink);
  else
    favoriteDrink = 0;
   
  return *this;
}

//  Destructor
Person::~Person()
{
  if (favoriteDrink != 0)
    delete favoriteDrink;  
}

// Constructor
SmartTurkey::SmartTurkey() :
  roasted(0) {}
 
  SmartTurkey::SmartTurkey(string makeTemp, Turkey* makeTemp1) :
    stuffing(makeTemp)
  {
    if (makeTemp1 == 0)
      roasted = 0;
    else
      roasted = new Turkey(*makeTemp1);
  }

// Copy constructor  
SmartTurkey::SmartTurkey(const SmartTurkey& other) :
  stuffing(other.stuffing)
{
  if (other.roasted != 0)
    roasted = new Turkey(*other.roasted);
  else
    roasted = 0;

 }
 
// Copy Assignment
SmartTurkey& SmartTurkey::operator=( const SmartTurkey& other)
{  
  if (this == &other) return *this;
 
  stuffing = other.stuffing;
 
  if (this->roasted != 0)
    delete roasted;
   
  if (other.roasted != 0)
    roasted = new Turkey(*other.roasted);
  else
    roasted = 0;
   
  return *this;
}

// Destructor
SmartTurkey::~SmartTurkey()
{
  if (roasted != 0)
    delete roasted;  
}

Toast::Toast():
  year(0), proposer(Person()){}
 
Toast::Toast( string bn, int y, Person p) :
  beverageName(bn),
  year(y),
  proposer(p){}
 
Turkey::Turkey():
  age(0){}
   
Turkey::Turkey( string n, int a, Person o) :
  name(n.c_str()),
  age(a)
  {
    owner = o;
  }
 
/*-------------------------------------------------------------------*/  

// Ostream for Date()  
ostream& operator<<( ostream& os, const Date* d)
{
  os << "Date: ";
  os << d->month << "/";
  os << d->day << "/";
  os << d->year << endl;
  return os;
}

// Ostream for DinnerParty
ostream& operator<<( ostream& os, const DinnerParty& dp)
{
  os << "Date of Party :" << &dp.partyDate;
  os << *dp.beverage;
 
  if (dp.storage != 0)
  {
    for (int i = 0; i < dp.storage; i++)
      os << (dp.courses[i]);
  }
 
  if (dp.gobblers.begin() != dp.gobblers.end())
  {
    vector<Person*>::const_iterator q = dp.gobblers.begin();
    while (q != dp.gobblers.end())
    {
      os << "Other people is/are :" << **q++;
    }
  }
  return os;
}

// Ostream for Person
ostream& operator<<( ostream& os, const Person& p)
{
  os << "Name Info: " << p.name << endl;
  if (p.favoriteDrink != 0)
    os << "Toast " << *(p.favoriteDrink) << endl;
 
  if (p.friends.begin() != p.friends.end())
  {
    vector<Person*>::const_iterator q = p.friends.begin();
    while (q != p.friends.end())
      cout << "Friends" << **q++;
      os << endl;
  }  
  return os;
}

// Ostream for SmartTurkey
ostream& operator<<( ostream& os, const SmartTurkey& p)
{
  os << "Stuffing : " << p.stuffing << endl;
  os << "Brand: " << *(p.roasted);
  return os;
}

// Ostream for Toast
ostream& operator<<( ostream& os, const Toast& t)
{
  os << "Type of Drink : " << t.beverageName << endl;
  os << "How Old: " << t.year << endl;
  os << "Toaster " << t.proposer;
  return os;
}


// OStream for Turkey
ostream& operator<<( ostream& os, const Turkey& t)
{
 os << "Name: " << t.name << endl;
 os << "Age:  " << t.age << endl;
 os << "Turkey Owner's " << t.owner;
 return os;
}

int main() {
  //OUTPUT6
  cout << "\n\nOUTPUT 6: " << endl;
  DinnerParty ALL(v, &bday, NumArray,temp, st);
  cout << ALL;  
} // main()

The output is :

OUTPUT 6:
Date of Party :Date: 11/14/2003
Type of Drink : Starbucks Coffee
How Old: 56
Toaster Name Info: Mike
FriendsName Info: Eric
FriendsName Info: David

My question is
1)why it's not showing the date after "Date of Party?"  
2)Why can't I write everything insdie of first class definition..instead, i have to write
class Toast;
class SmartTurkey;
class Turkey;
class Person;

at the beginning of the code and the rest of definition (like..copy contructors..etc..after the first class definition).  This works because I followed my textbook.

Sorry about this long code..i am just really curious abouto this problem...Thanks  Any hint will be appreicated..

Thanks
daskino12Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

n_fortynineCommented:
1) What do you mean? Didn't the output show:
>>Date of Party :Date: 11/14/2003
2) Because one class is using another and itself in turn is being used by the "other" (for example: Toast uses Person and Person uses Toast.) Technically you don't have to declare Turkey at all just need to make sure Turkey is defined above DinnerParty. If you have class A using class B, the compiler will look for any reference to class B PRIOR to that position of code (or in any included files), and it must known what B is or at least B is declared.
0
daskino12Author Commented:
Hello,

I am sorry about the first question. I got it...i got somethign wrong...anyway, thanks..i undersatnd the second questions now.

I was just wondering, is it possible for me to put  Ostream part inside of my first class definition?  I have tried it yet it gave me errors..

Thanks
0
daskino12Author Commented:
Hello,

I am sorry but from my textbook, it didn't declare all the class at the beginning of the program.  Do you know why?  I thought you have to do that (according to  n_fortynine's comments).  Or, it is not necessary...

THanks
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

n_fortynineCommented:
>>I was just wondering, is it possible for me to put  Ostream part inside of my first class definition?  I have tried it yet it
>>gave me errors..
Could you please be more specific, say, which class is it? normally you have to make it a friend.
friend ostream& operator << ( ... )
0
bcladdCommented:
Usually  the function

ostream& operator<<

is used between an ostream and an object of a user defined class to "print out" the object (or rather to insert the object into the stream). When you put binary operators into a class, the left hand side of the operator MUST be an object of the defining class. So, you could define an operator<< inside of Toast (for example), but it could only work if the left hand side of << (when used) is of type Toast. Since you want to insert a Toast into an output stream you must either:
(1) Modify the definition of the class ostream
(2) Write a global operator that specifies both the left hand and right hand sides of the operator.

(1) Is infeasible. (2) works an usually you make the operator a friend so that it is part of the class interface and can access private data members of the class.

Hope this helps,
-bcl
0
daskino12Author Commented:
Hello,

So, for example, i can do theh following:

using namespace std;

class Toast;
class SmartTurkey;
class Turkey;
class Person;

// To init.
class Date {
    int month;
    int day;
    int year;

public:
    //Date(): month(0), day(0), year(0) {};
    Date();
    Date( int m, int d, int y );

    friend ostream& operator<<( ostream& os, const Date* d );
}; // class Date {}

..

..

/* Date */

Date::Date() :
month(0), day(0), year(0) {}
Date::Date( int m, int d, int y ): month(m), day(d), year(y) {}
ostream& operator<<( ostream& os, const Date* d)
{
  os << "Date: ";
  os << d->month << "/";
  os << d->day << "/";
  os << d->year << endl;
  return os;
}

all in one block, right?

THanks
0
daskino12Author Commented:
Hello,

Ok.  Now, one of my unclear question above is, can I write everything at the first part of class

Like

class Date {
    int month;
    int day;
    int year;

public:
    //Date(): month(0), day(0), year(0) {};
    Date();
    Date( int m, int d, int y );

    friend ostream& operator<<( ostream& os, const Date* d );
}; // class Date {}

without declearing the following then?

class Toast;
class SmartTurkey;
class Turkey;
class Person;

Um..it seems it doesn't work because as  n_fortynine said, for eample, Toast used Person..Person uses Toast..but is there a way to do it differetly?  The reason i am asking this is because i think i have leart a way but i just forgot how to do it...not too sure..anyway...thanks:)

0
n_fortynineCommented:
daskino12:

If a class, say Date does not use any other classes then it can be defined BEFORE any other classes THAT USES IT without having to forward declare it. Otherwise, C++ does not allow a way around it.

For example:

class ClassThatDateUseIfAny {
  //...
};

class ClassThatDoesNotUseDate {
  //...
};

class Date {
  //...
};

class ClassThatUsesDate {
  //...
};

0
daskino12Author Commented:
Hello,

I am sorry..can u like.plez .explain a bit more? I am so sorry.i. am a beginner...

Thnaks
0
n_fortynineCommented:
Well, in short here's how it goes. You CANNOT use a class without the compiler knowing what it is.

class A {
   B instance_of_B; //compiler does not know what B is consist of to handle this.
};

so you'll have to do AT LEAST the following, which is called forward declaration:

class B; //notice that you don't have to give the detailed description of class B at this moment.

class A {
   B instance_of_B; //now compiler's assured that B is a technically "known" type, so it's OK with it.
};

and then at some point later you can "describe" B:

class B {
//blah blah blah
};

Now back to your case:
You have Toast using Person and Person using Toast. These are interleaved and if you do not forward declare at least one, you'll get errors thrown at you by the compiler. Even so, you DO NOT have to forward declare both of them. This is dependent upon your order in which you define Toast and Person. For ex:

Case 1: You define Toast first, then Person.

class Toast {
  //using Person.
};

class Person {
 //using Toast.
};

Here BEFORE Toast the compiler will need to know what Person is so only forward declaration of Person is needed.

class Person;

class Toast {
  //using Person.
};

If you have a class that has no relationship with the others then obviously there is no need to forward declare it. It is only a matter of style that your book is choosing, and it chooses to forward declare everything.

Does that make things much clearer?
class Person {
 //using Toast. Notice now the compiler has already known what Toast is since it's defined/declared ABOVE this.
};

Case 2: You declare Person first, and then Toast.
Now using the same argument you can see that Toast's the only one that needs to be forward declared.

class Toast;

class Person {
 //using Toast.
};

class Toast {
  //using Person.
};

Do
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
daskino12Author Commented:
Hello,

Thank you so much.  It makes sense now.

Thanks

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.