Thread: Double Pointer, dynamic allocation help

1. Double Pointer, dynamic allocation help

I'm writing a program involving a theoretical hotel. Most of the code is already written, but the part I'm having trouble with involves the very beginning of the code.

The program is designed to read in from an input file the hotel's ID number, the types of rooms it has, the Room Numbers of each room, the base rate for each room, and the rate of additional charge per person.

The code demonstrates inheritance for my Object-Oriented Programming class, as each type of room will inherit from generic class Room, but I can't seem to figure out how to make the double-pointer for dynamic allocation work.

The code is below.

Hotel.h
Code:
```class Hotel{
int hotelID;
static const int MAX_SIZE = 101;
Room **rPoint;

public:
Hotel(void);
~Hotel(void);
void setHotelID (int ID);
int getHotelID();
void setHotelRooms(int max, int min, Room &rPoint, char type);
int checkOpenRooms();
void checkin(Customer c, Room r);
void checkout(Room r);
};```
hotel.cpp (void Hotel::setHotelRooms)
Code:
```void Hotel::setHotelRooms(int max, int min, Room &rPoint, char type){
//rPoint is the variable from the Hotel class, being passed here.
rPoint = new Room *[MAX_SIZE];
for (int c = min; c<=max; c++)
{
switch (type)
{
case 'P':
Room[c] = new *Penthouse;
break;
case 'S':
Room[c] = new *Suite;
break;
case 'K':
Room[c] = new *King;
break;
case 'D':
Room[c] = new *DoubleRm;
break;
default:
break;
}

return;
}
}```

2. If you are permitted to do so, use a std::vector<std::shared_ptr<Room>> instead of a Room**. It is possible that shared_ptr is not yet available in the standard library that you can use, in which case use a std::vector<Room*>, then get your Hotel class to manage the memory for the Room pointers.

Whether you use a std::vector<Room*> or have to stick with Room**, note that once you do manual memory management, you need to care about the copy constructor, copy assignment operator and destructor. It seems that you did declare (and presumably defined) the destructor, but you should also define the copy constructor and copy assignment operator or declare them private to disable them.

Now, concerning the code that you showed. This is wrong:
Code:
`Room[c] = new *Penthouse;`
It should be:
Code:
`Room[c] = new Penthouse;`
Furthermore, look carefully at the placement of the return statement in the setHotelRooms member function. Since the return statement is unnecessary here, I suggest that you remove it. Incidentally, if you want to specify that a function takes no arguments, just leave its parameter list empty as it is not common C++ style to use the void keyword for that purpose.

By the way, getHotelID sounds like it should be a const member function.

3. It should be
Code:
```rPoint[c] = new Penthouse;
//etc.```
(But why are your rooms called points?)

And (if you have your heart set on not using a vector, etc) why not just declare rPoint as an array of MAX_SIZE pointers in the first place?

4. Fixed several errors in the entire program (by removing one of the asterisks for Room **room because it was unnecessary). Now, I receive two errors, both pertaining to the same code. Updated code below, errors before that.

Errors:
Code:
```1>c:\users\trey\documents\visual studio 2010\projects\oop program 1\oop program 1\hotel.cpp(21): error C2511: 'void Hotel::setHotelRooms(int,int,Room &,char)' : overloaded member function not found in 'Hotel'
1>          c:\users\trey\documents\visual studio 2010\projects\oop program 1\oop program 1\hotel.h(9) : see declaration of 'Hotel'```
Hotel.h
Code:
```class Hotel{
int hotelID;
static const int MAX_SIZE = 101;

public:
Hotel(void);
~Hotel(void);
Room *room;
void setHotelID (int ID);
int getHotelID();
void setHotelRooms(int max, int min, char type);
int checkOpenRooms();
void checkin(Customer c, Room r);
void checkout(Room r);
};```
Hotel.cpp (void setHotelRooms)
Code:
```void Hotel::setHotelRooms(int max, int min, Room &room, char type){
room = new Room *[MAX_SIZE];
for (int c = min; c<=max; c++)
{
switch (type)
{
case 'P':
room[c] = new Penthouse;
break;
case 'S':
room[c] = new Suite;
break;
case 'K':
room[c] = new King;
break;
case 'D':
room[c] = new DoubleRm;
break;
default:
break;
}
}
}```

5. Originally Posted by Trey Brumley
by removing one of the asterisks for Room **room because it was unnecessary
A Room** may be necessary since a hotel will presumably have rooms of different subtypes. With just a Room*, you would be allocating a dynamic array of objects of a single subtype (unless you're going with say, a linked list approach, which does not seem to be the case here).

To fix the error you get, look carefully at your declaration of setHotelRooms in the header and its definition in the source file. The function signature should match.

6. Now in the main program, I'm getting a bunch of error C2228s (function must have a class/struct/union) for class Room, and all the Room identifiers are listed as undeclared.

For example,
Code:
`charge = hotel.*room[rn].calculateBill(hotel.*room[rn].getNights(), hotel.*room[rn].getOccNum(), hotel.*room[rn].getBaseRate(), hotel.*room[rn].getAddRate());`
In the above case, "left of '.calculateBill' must have class/struct/union." and "'room' : undeclared identifier"

Room.h
Code:
```class Room    {
private:
int occNum;
int nights;
int MaxOccNum;
double baseRate;
bool smoking;

public:
Room(void);
~Room(void);
Customer customer;
void setSmoking(int i, int s);
bool isOccupied();
bool isSmoking();
int getNights();
void setNights(int days);
int getOccNum();
void setOccNum(int ppl);
int getMaxOccNum();
void setMaxOccNum(int max);
double getBaseRate();
void setBaseRate(double rate);
double calculateBill(int night, int occNum, double rate, double add);
void assignCustomer(string nm, string cc, bool emp);
void modify();
void clearRoom();
};```
Room.cpp
Code:
```Room::Room(void){
};

Room::~Room(void)
{
};

void Room::setSmoking(int i, int s)
{
if (i <= s)
smoking = true;
else
smoking = false;

return;
}

bool Room::isSmoking()
{
return smoking;
}

int Room::getNights() {return nights;};

void Room::setNights(int days)
{
nights = days;
return;
};

int Room::getOccNum() { return occNum; };

void Room::setOccNum(int ppl)
{
occNum = ppl;
return;
};

bool Room::isOccupied()
{
return (getOccNum() > 0);
}

double calculateBill(int night, int occNum, double base, double add)
{
double charge;
charge = charge*night;

return charge;
}

//In case a room needs to be modified (e.g. add nights or occupants), this function enables that.

void Room::assignCustomer(string nm, string cc, bool emp)
{
customer.setName(nm);
customer.setCCNum(cc);
customer.setEmployee(emp);
return;
}

void Room::clearRoom()
{
customer.setName("");
customer.setCCNum("");
customer.setEmployee('N');
setOccNum(0);
setNights(0);

return;
}

int Room::getMaxOccNum()
{
return MaxOccNum;
}

void Room::setMaxOccNum(int max)
{
MaxOccNum = max;
return;
}

double Room::getBaseRate()
{
return baseRate;
}

void Room::setBaseRate(double rate)
{
baseRate = rate;
return;
}

{
}

{
return;
}```

7. I do not see include for your header file in the cpp file

8. iostream and <class>.h are included. I just cut straight to the constructor methods.

9. If you just have a single star now (ie Room * room), then hotel.*room[rn] does not exist, because hotel.room[rn] is no longer a pointer, but a simple Room.

10. Originally Posted by Trey Brumley
In the above case, "left of '.calculateBill' must have class/struct/union." and "'room' : undeclared identifier"
That is because you are using the wrong syntax for what you want to do. You probably want to dereference the member pointer, but you are using syntax that looks like you are dereferencing a pointer to the member instead.

With a Room**, I would expect:
Code:
```charge = hotel.room[rn]->calculateBill(hotel.room[rn]->getNights(),
hotel.room[rn]->getOccNum(),
hotel.room[rn]->getBaseRate(),
With a Room*, this will do:
Code:
```charge = hotel.room[rn].calculateBill(hotel.room[rn].getNights(),
hotel.room[rn].getOccNum(),
hotel.room[rn].getBaseRate(),