classes

I know nothing about classes other then what I read in my shitty text book. I am trying to get this program to work, but I keep getting this error "no matching function for call to Bus::Bus(). I tried googling, but there is a lot of things I just do not understand, so I cannot figure it out. If I delete all the constructor jargin, it will compile, but values will not be set to 0. Another problem is I cannot get the busDriverName to actually transfer its value to the variable for later use, it just results in a " " when choosing option 5 (when I didn't have constructors).

Side note: I tried to divide the program into the implementation file, and all that, but my text book is not clear, nor do I have any idea on how to do it, so it is all one giant code. I am using Dev C++.


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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include <iostream>
#include <iomanip>
#include <limits>

using namespace std;

const int MAX_SPEED = 50;
const int MIN_SPEED = 0;
const int ACCELERATE = 5;
const int DECELERATE = -5;

class Bus
{	
	public:
		string busDriverName;
		int speed;
		int numberOfSeats;
		int busIDNumber;
		Bus (string);
		Bus (int, int, int);
		
	int busMenuOptions () // menuOptions function declaration, and initialization
	{
		int choice;
		
		do
		{
			cout << setfill('*'); // instructs the program to insert a * whenever the code setw() is present
			cout << "Make a selection from the menu below:" << endl; // Instructs the user to enter a menu option
			cout << "*" << setw(29) << "*" << endl; // Blocks the menu out in *
 			cout << "MAIN MENU \n"; // outputs the text in ""
 			cout <<	"1. Set the bus ID number \n";
 			cout <<	"2. Set the number of seats on the bus \n";
 			cout <<	"3. Set the bus driver's name \n";
 			cout << "4. Accelerate or decelerate\n";
 			cout <<	"5. display bus information \n";
			cout << "6. Quit Program \n" ;
 			cout << "*" << setw(29) << "*" << endl;
 			cout << "Please enter your selection now: ";
 		
			cin >> choice; // accepts the user input and saves it as choice
		
			do 
			{
				if (!cin)
				{
					cout << "Invalid input \n" << endl;
					cin.clear();  // Clears the input stream.
					cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // Clears the input buffer.
					cout << "Please enter a valid menu selection: "; // tells the user to to enter the value
					cin >> choice; 
				}
				
			}
			while (!cin);
			cout << endl;
			
			switch (choice) // switch structure to compare the user input choice with the switch statement
			{
			case 1: // if 1 is selected case 1 is initialized
				Bus::setBusID(busIDNumber);
				break; // terminates the switch structure
			
			case 2: // if 2 is selected case 2 is initalized
				Bus::setSeats(numberOfSeats);
				break; // terminates the switch structure
			
			case 3: // if 3 is selected case 3 is initialized
				Bus::setBusDriver(busDriverName);
				break; // terminates the switch structure
				
			case 4:
				Bus::accelerateDecelerate(speed);
				break;	
			
			case 5: // if 4 is selected case 4 is initialized
				displayBus (busIDNumber, numberOfSeats, busDriverName, speed);
				break; // terminates the switch structure

			case 6: // if 5 is selected case 5 is initialized
				cout << "Thanks for using the bus program!" << endl;
				system ("Pause");
				return 0;
			
			default :
				cout << "Invalid selection, please try again. \n" << endl; // if anything other than the choices of the switch structure is entered the switch loop will repeat and "Invalid selection, please try again will be displayed"
			}
		}
		while (choice != 6);
				
	}
	void setBusDriver(string busDriverName)
	{
		cout << "Enter the name of the bus driver: \n" << endl;
		cin >> 	busDriverName;
		
		if (!cin)
		{
				cout << "Invalid input \n" << endl;
				cin.clear();  // Clears the input stream.
				cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // Clears the input buffer.
				cout << "Please enter a name for the bus driver : "; // tells the user to to enter the value
				cin >> busDriverName;
				cout << endl << "Thank you!" << endl;	
		}
	}
	
	void setBusID (int busIDNumber)
	{
		cout << "Enter the id number of the bus: ";
		cin >> busIDNumber;
		cout << endl;
	}
	
	void accelerateDecelerate (int choice)
	{
	
		cout << "To accelerate the bus press 1, to decelerate press 2";
		cin >> choice;
		
		switch (choice)
		{
			case 1:
				if (speed < MAX_SPEED)
					speed += ACCELERATE;
				break;
			case 2:
				if (speed > MIN_SPEED)
					speed += DECELERATE;
				break;
			default:
				cout << "Invalid input, please try again" << endl;
		}
	}
	
	void setSeats (int & numberOfSeats)
	{
		cout << "Please enter the total seats on the bus: ";
		cin >> numberOfSeats;
		
		if (!cin)
		{
				cout << "Invalid input \n" << endl;
				cin.clear();  // Clears the input stream.
				cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // Clears the input buffer.
				cout << "Please enter the number of seats : "; // tells the user to to enter the value
				cin >> numberOfSeats;	
		}		
		cout << endl;
	}
	
	void displayBus (int & busIDNumber, int & numberOfSeats, string busDriverName, int & speed)
	{
		cout << "The bus id number: " << busIDNumber << " is driven by " << busDriverName << " , with a maximum seating of\n " << numberOfSeats << ". Current speed is: " << speed << endl;
		
	}
};


Bus::Bus (string busDriverName)
	{
		busDriverName = "Dave";
	}
	
Bus::Bus  (int speed, int busIDNumber, int numberOfSeats)
	{
		speed =0;
		busIDNumber =0;
		numberOfSeats=0;
	}



int main()
{
	Bus info;

	info.busMenuOptions();
	
	
	return 0;
}
Last edited on
How does this even compile for you? Immediately I can see that you are not making use of any of your constructors. You define 2 constructors, one that takes in a string parameter, the other takes 3 integers, yet you use none of them when you instantiate an object from the Bus class in your main(). If you just want to nullify everything and add a default name to your bus driver, do something like this instead:

1
2
3
4
5
6
7
	Bus()
	{
		speed = 0;
		numberOfSeats = 0;
		busIDNumber = 0;
		busDriverName = "some person";
	}


Remove the other two constructors that you have.

Member initializer list syntax:
1
2
3
Bus::Bus()
 : busDriverName("some person"), speed(0), numberOfSeats(0), busIDNumber(0)
{}



There are some class member functions that the compiler automatically generates if the user does not. The default constructor is one of them. However, compiler auto-generates it only if the class has no user-defined constructors.

You have defined two:
1
2
Bus (string);
Bus (int, int, int);


Line 176 requires the default constructor. You could add one:
1
2
3
Bus ();
Bus (string);
Bus (int, int, int);


OR
change the line 176 to use one of the two constructors that you do have:
Bus info( "John Doe" );
It didn't compile for me unless I didn't have the constructor. The text book lead me to believe that the constructor was called out, and then defined later on, and I think the explanation was information hiding purposes, so that's why I did it that way. I changed them to a single one, and it works. I was wondering how to exactly use the default constructor. Would it just be like this:

Bus (int, int, int)

or

1
2
3
4
Bus ()
speed =0;
numberOfSeats =0;
busIDNumber =0;
Well thanks for the help, It all works now, but I do not know how to use another constructor to set the name of the driver. I have to use a user defined constructor to do so rather than the default, but it isn't working if I try to set the bus drivers name in it's own constructor.
So, think of a constructor as a function of your class that is executed when you create new objects of that class. They are very useful for setting initial values for certain variables or allocating memory on the heap (or freestore). Every class has a default constructor, even a struct has a default constructor. A default constructor does not have any parameters, however, it is perfectly fine to have a constructor that can have parameters. This helps you to assign initial values to an object at the time of its creation. It is also perfectly legal to have multiple different constructors for a class.

Now, you can only use one constructor when you create an object from a class. If you want to use another constructor that you have defined for your class, you'd have to create another object from said class using the appropriate constructor.

In the constructor that I showed you, I overwrite the default constructor to initialize certain values that you had. Then in main, all I have to do is create an object from that class without passing in any parameters as the constructor I created does not take in any parameters. This will cause the constructor I defined to be executed and set all the variables to their initial values. However, you could have another constructor like this:

1
2
3
4
5
6
Bus::Bus(int _speed, int _numOfSeats, int _busIdNum)
{
speed = _speed;
numberOfSeats = _numOfSeats;
busIDNumber = _busIdNum;
} 


then in main, you'd do something like this:

Bus myBus(90, 30, 1); // 90 for speed, 30 for total number of seats, 1 for bus id

This will cause the constructor that takes in 3 integer parameters to be executed. You could also use a member initializer list to set the values in the constructor like so:

1
2
3
4
5
Bus::Bus(int _speed, int _numOfSeats, int _busIdNum)
 : speed(_speed), 
    numberOfSeats(_numOfSeats),
    busIDNumber(_busIdNum)
{ /* You could do something else here if you wanted to */ }


Hope this clears things up a bit.
Each constructor version should moke sure that the entire object is appropriately initialized:
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
// default constructor (means "no arguments")
Bus::Bus()
 : busDriverName("some person"), speed(0), numberOfSeats(0), busIDNumber(0)
{
  // nothing in function body
}

// constructor that takes a name
Bus::Bus( string name )
 : busDriverName(name), speed(0), numberOfSeats(0), busIDNumber(0)
{
  // nothing in function body
}

Bus::Bus( int _speed, int numOfSeats, int busIdNum )
 : busDriverName("some person"),
   speed(_speed),
   numberOfSeats(numOfSeats),
   busIDNumber(busIdNum)
{
  // nothing in function body
}


int main()
{
  Bus foo; // default construction
  Bus bar( "John" );
  Bus gaz( 42, 7, 101 );
}



Note that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Bus::Bus(int _speed, int _numOfSeats, int _busIdNum)
{
  speed = _speed;
  numberOfSeats = _numOfSeats;
  busIDNumber = _busIdNum;
}

// means same as
Bus::Bus(int _speed, int _numOfSeats, int _busIdNum)
 : busDriverName(), speed(), numberOfSeats(), busIDNumber()
{
  speed = _speed;
  numberOfSeats = _numOfSeats;
  busIDNumber = _busIdNum;
}

The initialization of members occurs before the body of the constructor.
The statements in the body are mere assignments that overwrite the already default initialized members.
Ok I think I have it figured out more. The default just sets the parameters to null values, and you put it in for good measure/ if you plan on using a defined constructor. And then the defined constructor, you just input values during the main to set them to whatever you want.

Does that sound correct?
Topic archived. No new replies allowed.