Click here to Skip to main content
15,881,173 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am storing Floor objects in Floor floor_arr[3] array. Then using this array to call Floor class display() function. The problem is available rooms are always 0 because of constructor. I guess the available rooms value is not being returned by getter function. Hence, how can my output be made correct? Here is my code:
C++
#include<iostream>
#include<string>
using namespace std;

class Floor {
private:
	int available_rooms;
public:
	Floor();
	void set_available_rooms(int ar);
	int get_available_rooms();
	void display();
};
class Hotel {
protected:
	string name;
	const int total_floors;
	int floor_number;
	Floor floor_arr[3];
public:
	Hotel();
	void set_floor_number(int fn);
	int get_floor_number();
	Floor set_floor_arr();
	virtual void display();
};

Hotel::Hotel() : total_floors{ 0 } {
	name = "5-STAR HOTEL";
	floor_arr[2] = { };
}
Floor Hotel::set_floor_arr() {
	for (int n = 0; n < get_floor_number(); n++) {
		floor_arr[n] = Floor();
		return floor_arr[n];
	}
}
void Hotel::set_floor_number(int fn) {
	floor_number = fn;
}
int Hotel::get_floor_number() {
	return floor_number;
}
void Hotel::display() {
	cout << "The available floors are: " << floor_number << endl;
	int x;
	cout << "Select Floor" << endl;
	cin >> x;
	switch (x) {
	case 1: floor_arr[0].display();
		break;
	case 2: floor_arr[1].display();
		break;
	case 3: floor_arr[2].display();
		break;
	default:
		cout << "Enter Valid Input" << endl;
		break;
	}
}

Floor::Floor() {
	available_rooms = 0;
}
void Floor::set_available_rooms(int ar) {
	available_rooms = ar;
}
int Floor::get_available_rooms() {
	return available_rooms;
}
void Floor::display() {
	cout << "The available rooms are " << available_rooms << endl;//output is 0
}

int main() {
	int a, b;

	Hotel obj;
	Floor obj1;

	cout << "Enter available floors" << endl;
	cin >> a;
	obj.set_floor_number(a);
	obj.set_floor_arr();
	cout << "Enter available rooms" << endl;
	cin >> b;
	obj1.set_available_rooms(b);

	obj.display();

	return 0;
}


What I have tried:

I tried using getter function in Floor class display function. But still the output was 0.
Posted
Updated 8-Jan-22 8:32am

You are calling the display method on your Hotel object and that displays the Floors within that Hotel, but you never correctly initialized the Floor objects stored inside your Hotel object. Instead you created and initialized a separate Floor object (which is not connected to your Hotel).

If you want to initialize your Hotel's Floors, you need to loop over these Floors and initialize each of them separately.


P.S.: since you asked for more help, I modified the code to include the initialization. Most importantly, I changed the two classes to let you construct them as fully initialized objects. The most prominent changes are the introduction of a factory method for your Floor class and the addition of a loop in main() to construct the floors of your hotel:
C++
#include<iostream>
#include<string>
#include <vector>
using namespace std;

class Floor {
private:
	int available_rooms;
public:
	Floor();
	Floor(const Floor& other_floor); // copy constructor - see below
	Floor& operator=(const Floor& other_floor); // copy assignment, see below
	static Floor make_floor_with_rooms(int number_of_rooms); // factory method - see below
	// getter and setter
	void set_available_rooms(int ar);
	int get_available_rooms();
	// utility functions
	void display();
};
class Hotel {
protected:
	string name;
	std::vector<Floor> floor_arr;
public:
	Hotel(const string& hotel_name); // Pass the name from outside, don't hide in implementation!
	void add_floor(const Floor& floor); // only add fully constructed Floor objects here
	void display();
};

Hotel::Hotel(const string& hotel_name) : name(hotel_name) {}
void Hotel::add_floor(const Floor& floor) {
    floor_arr.push_back(floor);
}
void Hotel::display() {
    auto floor_number = floor_arr.size(); // query number from floors vector
	cout << "The available floors are: " << floor_number << endl;
	int x;
	cout << "Select Floor" << endl;
	cin >> x;
	if (x < 1 || x > floor_number)
		cout << "Enter Valid Input" << endl;
	else
	    floor_arr[x-1].display(); // no switch statement needed
}

Floor::Floor() {
	available_rooms = 0;
}
Floor::Floor(const Floor& other_floor) { // copy constructor - see below
    // this is required to use the container class, std::vector
    available_rooms = other_floor.available_rooms;
}
Floor& Floor::operator=(const Floor& other_floor) { // copy assignment, see below
    // this is required to use the container class, std::vector
    available_rooms = other_floor.available_rooms;
    return *this;
}
Floor Floor::make_floor_with_rooms(int number_of_rooms) {
    // this is a helper function to create a Floor object that is fully initialized
    // this is a good way to make sure that you don't construct invalid objects
    Floor new_floor; // default constructor sets rooms to 0
    new_floor.set_available_rooms(number_of_rooms);
    return new_floor; // now we have a fully initialized object
}
void Floor::set_available_rooms(int ar) {
	available_rooms = ar;
}
int Floor::get_available_rooms() {
	return available_rooms;
}
void Floor::display() {
	cout << "The available rooms are " << available_rooms << endl;//output is 0
}

int main() {
	int a, b;

	Hotel my_hotel("Hotel California"); // create an initialized hotel object

	cout << "Enter available floors" << endl;
	cin >> a;
	
	// now iterate over the requested number of floors to create and initialize them
	for (int i = 0; i < a; ++i) {
	    cout << "Floor " << i+1 << ". "; // add a little information to guide the input
    	cout << "Enter available rooms" << endl;
    	cin >> b;
    	// now create an initialized Floor object with the required number of rooms
	    my_hotel.add_floor(Floor::make_floor_with_rooms(b));
	}

	my_hotel.display();

	return 0;
}
 
Share this answer
 
v2
Comments
0x01AA 8-Jan-22 14:41pm    
Makes sense, 5 ;)
Sheeda Bro 8-Jan-22 16:47pm    
I did this in
```
int main()
Hotel obj;
Floor obj1;
for (int n = 0; n < obj.get_floor_number(); n++) {
obj.get_floor_arr(obj1);
}
```
But still did not get the required output. Sorry, I am new to this so I don't understand well.
Stefan_Lang 8-Jan-22 17:51pm    
I updated the solution to include the change I suggested (and a few more improvements). Note that I eliminated some functions that are no longer needed with the new approach.
Sheeda Bro 9-Jan-22 4:22am    
I highly appreciate your efforts. I did not know about the factory method until now. So now I will practice vectors and factory method. Thanks a lot.
Stefan_Lang 9-Jan-22 5:46am    
std::vector is the most important of the container classes. You can and indeed should read up on it e. g. here: https://en.cppreference.com/w/cpp/container/vector

As for factory methods, that is just one way of constructing objects in C++, but it is, in fact the one I find to be most useful.

The most common way to construct objects is using constructors with arguments like @merano99 suggested in the comment below. However, I prefer actual methods over constructors because they let you use a meaningful name for the function, and let you do some things that a constructor cannot do.
You mismatching the objects. Writing "Clear code" with better names would help you to avoid such bugs. Change to:
C++
int main() {
	int floorInput, roomsInput;

	Hotel hotel;
	Floor floor;

Use the debugger for further details.
 
Share this answer
 
Comments
Stefan_Lang 8-Jan-22 14:18pm    
I'm not sure who downvoted you, but naming an object after the class isn't any better than using one-letter names. Of course in code like this there are rarely any meaningful objects, but e. g. myHotel, yourHotel, hotelCalifornia or hotelTransilvania are most certainly better choices for hotel object names.

In comparison, 'hotel' does not confer any meaning that you couldn't also get by hovering your mouse over the name and reading the tool tip showing the type...
0x01AA 8-Jan-22 14:29pm    
In my opinion hotel is much more usefull than obj ;)
Stefan_Lang 8-Jan-22 14:38pm    
Only when you're not using an editor that can show you the type of an object just by hovering over the name. It doesn't confer any information. You may argue that using 'hotel' will make it less likely to introduce errors to your code, but modern editors and good code structure will prevent that kind of error anyway.

So, yes, it may be an improvement, but it's still a long way from a good name.

That said, I dislike names that are different from other names just by capitalisation (one reason why I hate C# naming conventions). It's too easy to mess your code up with a typo, and too hard to spot such errors to be worth not spending a second or two to find a better name.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900