Thread: Double Pointer, dynamic allocation help

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    73

    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. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    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?
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    Registered User
    Join Date
    Nov 2012
    Posts
    73
    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. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote 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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Nov 2012
    Posts
    73
    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;
            double addRate;
            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 getAddRate();
            void setAddRate(double add);
            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;
        double addRate = add*(occNum-1);
        charge = addRate+base; 
        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;
    }
    
    
    double Room::getAddRate()
    {
        return addRate;
    }
    
    
    void Room::setAddRate(double add)
    {
        addRate = add;
        return;
    }
    Last edited by Trey Brumley; 10-24-2013 at 12:37 PM.

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    I do not see include for your header file in the cpp file
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Registered User
    Join Date
    Nov 2012
    Posts
    73
    iostream and <class>.h are included. I just cut straight to the constructor methods.

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    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. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote 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(),
                                           hotel.room[rn]->getAddRate());
    With a Room*, this will do:
    Code:
    charge = hotel.room[rn].calculateBill(hotel.room[rn].getNights(),
                                          hotel.room[rn].getOccNum(),
                                          hotel.room[rn].getBaseRate(),
                                          hotel.room[rn].getAddRate());
    Quote Originally Posted by tabstop
    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.
    Not really: the syntax is not appropriate to begin with so it would not have worked either if the member was a Room**.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by laserlight View Post
    Not really: the syntax is not appropriate to begin with so it would not have worked either if the member was a Room**.
    Oh right, pointer-to-member. Something was ringing faint bells, but not nearly loud enough for me to figure out why it wasn't a total error (although I could see from the message that it wasn't, hence....)

  12. #12
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Should the calculateBill member function really need to have those values passed into it? Seems to me that the function doesn't/shouldn't need anything to be passed in, it can just internally call the member functions (getNights, getOccNum, getBaseRate, getAddRate) to get those values it needs for its calculations.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dynamic memory allocation using pointer to pointers
    By mp252 in forum C++ Programming
    Replies: 12
    Last Post: 06-22-2013, 05:34 PM
  2. pointer to function and dynamic allocation
    By cfdprogrammer in forum C Programming
    Replies: 7
    Last Post: 07-08-2009, 10:36 AM
  3. pointer to array with dynamic allocation
    By cfdprogrammer in forum C Programming
    Replies: 22
    Last Post: 04-07-2009, 09:56 AM
  4. Dynamic mem allocation, how to get it right?
    By Subsonics in forum C Programming
    Replies: 31
    Last Post: 02-08-2009, 01:41 PM
  5. Double Pointer Memory Allocation: Problems
    By loopshot in forum C Programming
    Replies: 3
    Last Post: 11-02-2006, 05:38 PM