Multiple Classes

I have a difficulty I need help to overcome. I am developing a program that uses more than 1 class. Variables defined in one class are used in other classes. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class X1 {
private:
   int a;
   int b;
public:
   X1() {
      a = 10;
      b = 20;
   }
};

class X2 {
private:
   int c;
   int d;
public:
   X2() {
      c = 5 + 2*a;
      d = 10 - 4*b;
   }
};

int main() {
   X2 Test;
   int e = 40 + 10*d;
   cout << e << endl;

   keep_window_open();
   return 0;
}


I get a compile error that variable a and b in class X2 are not declared and initialized. I tried making X2 a sub-class of X1, hoping that X2 would inherit the variables a and b, but IO got even more compile errors.

My question: Is there a way to link the classes so that the variables of a prior class are known and usable in the subsequent classes? Or will I have to make one HUGE class?

Thanks in advance.

EDIT: Semi colons were changed to colons.
Last edited on
Well, if you want X2 to be able to use X1's a and b, why make a and b private? Either make them public or write get() functions for them. You could make X2 inherit from X1, but that still wouldn't work if a and b were left private (they'd need to be declared protected or public.)

Note:
The a and b in your X2 constructor are not the same variables a and b in the X1 class.

You have semicolons after your public declarations on lines 5 and 16. Make sure to change those to colons.
note that making those variables public or giving them getters won't solve another problem.

You can't get variables in X1 without having an X1 object. X2 doesn't have an X1 object.


Really, it smells like you have a design problem. Why don't you explain what it is you're really trying to do and maybe we can suggest a better way to go about it.
Stroustrup has an exercise in which the reader makes the "Hunt the Wumpus" game. My first step was to create the starting room. This is that code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "../../std_lib_facilities.h"

class Initialize {
private:
	double rand_wumpus;
	double rand_pit;
	double rand_bat;

public:
	Initialize() {
	double srand((unsigned)time(0));
        rand_wumpus = 100.0 * rand()/RAND_MAX;
        rand_pit = 100.0 * rand()/RAND_MAX;
        rand_bat = 100.0 * rand()/RAND_MAX;
	}
};


class Current_room {
private:
	int room_num;
	bool wumpus_in_room;
	bool pit_in_room;
	bool bat_in_room;

public:
	Current_room() {
        if (rand_wumpus > 10.5 && rand_wumpus < 12.2) {
		wumpus_in_room = true;
		cout << "The wumpus is in the room.  You are eaten!" << endl;
	} else {
		wumpus_in_room = false;
	}

	if (rand_pit > 30.1 && rand_pit < 41.8) {
		pit_in_room = true;
		cout << "You have fallen into a pit and died!" << endl;
	} else {
		pit_in_room = false;
	}

    if (rand_bat > 62.4 && rand_bat < 75.0) {
		bat_in_room = true;
		cout << "A bat has taken you to another room!" << endl;
	} else {
		bat_in_room = false;
	}
	if (wumpus_in_room == false && pit_in_room == false && bat_in_room == false) {
		cout << "You are safe!" << endl;
	}
	}
};


int main()
{
Current_room Test;

keep_window_open();
return 0;
}


The Current_room class is not accessing the rand_wumpus, rand_pit, and rand_bat variables form the Initialize class. The suggestions are to make Initialize public, use get() functions for those variables, or make Current_room a sub-class of Initialize. I don't which is best.
Last edited on
Okay -- you have some weird ideas of what classes are, which is probably why you're having this trouble. These classes make no sense, and therefore the overall structure is rather flawed.

Classes represent a "thing". You can create "objects" of classes. These objects represent a single instance of that thing.

For example here's a very simple class:

1
2
3
4
5
class Person
{
public:
  int age;
};


You can make "objects" of this class. For example:

1
2
3
Person bob;  bob.age = 20;
Person sue;  sue.age = 19;
Person jeff; jeff.age = 28;


bob, sue, and jeff are all "objects". Each one of them has their own age. bob can have a different age from sue, etc.

Now, you can't just access 'age' from Person. Something like this doesn't make any sense. Note that this is exactly what you are trying to do with your Initialize class, just rephrased:

1
2
3
4
5
6
7
8
9
10
class Person
{
public:
  int age;
};

int main()
{
  cout << age;  // I want to print the 'age' from 'Person' ?
}


That doesn't make any sense. Whose age are you printing? Jeff's? Sue's? All Persons have different ages. There's no one age that is used by all Persons. Therefore if you need to print someone's age.. you need an object:

1
2
3
4
int main()
{
  cout << jeff.age;  // now this makes sense.  We're printing Jeff's age
}



That's how classes work. They represent "thing"s.

Person represents a person with an age
std::string represents some textual data
std::list represents a linked list data container
std::ofstream represents a file
etc


With that in mind.... what does Initialize represent? Initialize is not a thing... so it really doesn't make any sense for it to be a class.

And what about Current_room? That's kind of a thing -- but it's not a thing in the same sense that Person/string/etc are. It's more like it's trying to be an object. Maybe "Room" would be a thing, and "Current_room" would be an object of Room, and not another class (similar to how 'jeff' is an object and there's no Jeff class)


So anyway, yeah. Your classes make no sense. All of the possible solutions that you mentioned at the end of your post are all equally valid and equally nonsensical.
Last edited on
@Disch,

Based on what I understand about this game, Hunt the Wumpus, the rooms between which the player moves seem to be the skeleton of the game. To me, the rooms represents a class. The rooms have 3 characteristics: the wumpus is present or not, a pit is present or not, and a bat is present or not.

I can see that the three 'states' of rooms; the room in which the player currently is, the adjacent rooms, and all other rooms, can be objects of a room class. As in current.room, adjacent.room, and other.room.

Initialize is a probability, intended to determine the starting state of the player. (A probability is a thing to me.) It seems better suited to be a characteristic of a room. So, based on your last post, it seems I should make Room a class, make Current an object in Room, and the booleans and probabilities are characteristics of Room. That would make Room Current; Current.rand_wumpus = 100*rand()/RAND_MAX; the way I should proceed.
Well, this code compiles and runs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "../../std_lib_facilities.h"

class Room {
public:
	double rand_wumpus;
	double rand_pit;
	double rand_bat;
	bool wumpus_in_room;
	bool pit_in_room;
	bool bat_in_room;
	int room_num;
};

int main() {
Room current;
	double srand((unsigned)time(0));
	current.room_num;
        current.rand_wumpus = 100.0 * rand()/RAND_MAX;
        current.rand_pit = 100.0 * rand()/RAND_MAX;
        current.rand_bat = 100.0 * rand()/RAND_MAX;

        if (current.rand_wumpus > 10.5 && current.rand_wumpus < 12.2) {
		current.wumpus_in_room = true;
		cout << "The wumpus is in the room.  You are eaten!" << endl;
	} else {
		current.wumpus_in_room = false;
	}

	if (current.rand_pit > 30.1 && current.rand_pit < 41.8) {
		current.pit_in_room = true;
		cout << "You have fallen into a pit and died!" << endl;
	} else {
		current.pit_in_room = false;
	}

        if (current.rand_bat > 62.4 && current.rand_bat < 75.0) {
		current.bat_in_room = true;
		cout << "A bat has taken you to another room!" << endl;
	} else {
		current.bat_in_room = false;
	}

	if (current.wumpus_in_room == false && current.pit_in_room == false && current.bat_in_room == false) {
		cout << "You are safe!" << endl;
	}

	cout << current.rand_wumpus << endl;
	cout << current.rand_pit << endl;
	cout << current.rand_bat << endl;

	keep_window_open();
        return 0;
}


One problem is that the random numbers are always the same unless the program is compiled again. I know it is due to the where the seed is generated. I should have the srand() line above the main() section.
Yes, that organization makes much more sense.

Initialize is a probability, intended to determine the starting state of the player. (A probability is a thing to me.)


Probabilities can certainly be things, yes. But then, at best, the class was poorly named.


One problem is that the random numbers are always the same unless the program is compiled again.


That shouldn't be the case. You should get new numbers every time you run the program. Compiling should have nothing to do with it.

Also, get rid of that 'double' on line 16.
Topic archived. No new replies allowed.