how can two class reference each other?

C

cppaddict

Hi,

Is it possible that class A references class B, and class B references class
A?

Specifically, here is my problem. I have a card table class (Table), which
represents
a table at which players might play blackjack or some other game. I also
have a Hand
class, which represents the various hands being played at the table. Thus
Table has
a member which is a list of Hand objects. However, it will sometimes be
convenient for
a Hand object to have a reference to the Table which contains it: eg, a
blackjack hand
might need to split itself, which would involve adding a new Hand to the
Table's list
of hands. So I thought I could make a Table& one of the members of Hand.
But now
the compiler has a chicken and egg problem: It has to compile one class
first, but whichever
class it does try to compile first will reference the other class, which is
not yet defined.

I think that either:

1. There is some general design pattern I should be using instead of
referencing a containing
object, and that this patter would solve my problem better.

2. There is some way to make this work.

Does anyone know?

Thanks,
cpp

In case the above description isn't clear enough, here is my (impossible to
compile) code:

#include "stdafx.h"
#include <string>
#include <algorithm>
#include <list>
using namespace std;

class Table {
private:
list<Hand> m_hands;
public:
void addHand(Hand h) {m_hands.push_back(h);}
void showHands() {
list<Hand>::iterator iter;
for (iter = m_hands.begin(); iter != m_hands.end(); iter++)
*iter.show();
}
};

class Hand {
private:
int m_card1;
int m_card2;
Table& m_table;
public:
void show() {cout << m_card1 << " " << m_card2 << endl;}
void setCards(int i) {m_card1 = i; m_card2 = i;}
int getCard1() {return m_card1;}
void split() {m_table.addHand(*this);}
};

int main() {
Table myTable;
Hand myHand;
myHand.setCards(1);
myTable.addHand(myHand);
myHand.setCards(2);
myTable.addHand(myHand);
myHand.split();
myTable.showHands();
system("PAUSE");
return 0;
}
 
J

jeffc

cppaddict said:
Hi,

Is it possible that class A references class B, and class B references class
A?

Specifically, here is my problem. I have a card table class (Table), which
represents
a table at which players might play blackjack or some other game. I also
have a Hand
class, which represents the various hands being played at the table. Thus
Table has
a member which is a list of Hand objects. However, it will sometimes be
convenient for
a Hand object to have a reference to the Table which contains it: eg, a
blackjack hand
might need to split itself, which would involve adding a new Hand to the
Table's list
of hands.

Yes, this is an interesting problem. Technically the hands belong to the
casino, and players can't touch them. On the other hand, players are the
only ones who can make decisions on their hands - the casino can't.
So I thought I could make a Table& one of the members of Hand.
But now
the compiler has a chicken and egg problem: It has to compile one class
first, but whichever
class it does try to compile first will reference the other class, which is
not yet defined.

I think that either:

1. There is some general design pattern I should be using instead of
referencing a containing
object, and that this patter would solve my problem better.

2. There is some way to make this work.

Use a pointer to the Table from the hand, not a reference. That way you can
define a forward reference. In general, it looks like this:
class A;
class B
{
A* ptrToA;
};
class A
{
B b;
};
 
D

David White

cppaddict said:
Hi,

Is it possible that class A references class B, and class B references class
A?

Specifically, here is my problem. I have a card table class (Table), which
represents
a table at which players might play blackjack or some other game. I also
have a Hand
class, which represents the various hands being played at the table. Thus
Table has
a member which is a list of Hand objects. However, it will sometimes be
convenient for
a Hand object to have a reference to the Table which contains it: eg, a
blackjack hand
might need to split itself, which would involve adding a new Hand to the
Table's list
of hands. So I thought I could make a Table& one of the members of Hand.
But now
the compiler has a chicken and egg problem: It has to compile one class
first, but whichever
class it does try to compile first will reference the other class, which is
not yet defined.

I think that either:

1. There is some general design pattern I should be using instead of
referencing a containing
object, and that this patter would solve my problem better.

2. There is some way to make this work.

Does anyone know?

Thanks,
cpp

In case the above description isn't clear enough, here is my (impossible to
compile) code:

#include "stdafx.h"
#include <string>
#include <algorithm>

You don't need said:
#include <list>

You do need said:
using namespace std;

class Table {

You have to put this class after the definition of class Hand.
private:
list<Hand> m_hands;
public:
void addHand(Hand h) {m_hands.push_back(h);}

This would be better as:
void addHand(const Hand& h) {m_hands.push_back(h);}
void showHands() {

Better as:
void showHands() const
list<Hand>::iterator iter;

list said:
for (iter = m_hands.begin(); iter != m_hands.end(); iter++)
*iter.show();

*iter.show() is wrong because the . has higher precedence than the *. Use
iter->show(). (If you really want to use the * and . then it needs to be
(*iter).show())

After moving this above class Table, use this forward declaration:

class Table;
class Hand {
private:
int m_card1;
int m_card2;
Table& m_table;

You need a constructor to initiatialize this reference member.
public:
void show() {cout << m_card1 << " " << m_card2 << endl;}

void show() const
void setCards(int i) {m_card1 = i; m_card2 = i;}
int getCard1() {return m_card1;}

int getCard1() const
void split() {m_table.addHand(*this);}

This member will have to move.
};

int main() {
Table myTable;
Hand myHand;
myHand.setCards(1);
myTable.addHand(myHand);
myHand.setCards(2);
myTable.addHand(myHand);
myHand.split();
myTable.showHands();
system("PAUSE");
return 0;
}

Here is the complete, corrected and rearranged code:

#include <list>
#include <iostream>

using namespace std;

class Table;

class Hand {
private:
int m_card1;
int m_card2;
Table& m_table;
public:
Hand(Table &table) : m_table(table) {}
void show() const {cout << m_card1 << " " << m_card2 << endl;}
void setCards(int i) {m_card1 = i; m_card2 = i;}
int getCard1() const {return m_card1;}
void split();
};

class Table {
private:
list<Hand> m_hands;
public:
void addHand(const Hand& h) {m_hands.push_back(h);}
void showHands() const {
list<Hand>::const_iterator iter;
for (iter = m_hands.begin(); iter != m_hands.end(); iter++)
iter->show();
}
};

inline void Hand::split() {m_table.addHand(*this);}

int main() {
Table myTable;
Hand myHand(myTable);
myHand.setCards(1);
myTable.addHand(myHand);
myHand.setCards(2);
myTable.addHand(myHand);
myHand.split();
myTable.showHands();
system("PAUSE");
return 0;
}
 

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

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top