0

I have a table object with the following header file:

#ifndef TABLE_H
#define TABLE_H
#include "Order.h"
#include "Waiter.h"

//                    0       1        2       3
enum TableStatus { IDLE, SEATED, ORDERED, SERVED };

class Waiter; // to take care of circular reference.

class Table 
{
private:
    int tableId;        // table number
    const int maxSeats; // table seat capacity
    TableStatus status; // current status, you can use assign like
                // status = IDLE;
    int numPeople;      // number of people in current party
    Order *order;       // current party's order
    Waiter *waiter;     // pointer to waiter for this table

public:
    Table(int tblid =0, int mseats = 0);    // initialization, IDLE
    void assignWaiter(Waiter *person);  // initially no waiter
    void partySeated(int npeople);      // process IDLE --> SEATED
    void partyOrdered(Order *order);    // process SEATED --> ORDERED
    void partyServed(void);         // process ORDERED --> SERVED
    void partyCheckout(void);       // process SERVED --> IDLE
    int getMaxSeats(void);
    int getStatus(void);
};
#endif

in my main function, I need to declare an array of tables. But when I write, say, Table *table = new Table[10], every element of the array calls the default arguments in the constructor, and every table ends up with a constant maximum seat value of 0. I need to be able to individually call each of their constructors to have different values for the maxSeats.

The only solution I've been able to come up with so far is to declare an array of pointers to table objects, and then instantiate each one separately. This partially works, but the Waiter class mentioned in the code above accepts an array of Tables as an argument, and won't work if it's passed an array of Table pointers.

What process can i perform to end up with an array of Table objects with differing values for their maxSeats constant variable?

One more point of clarification: The array has to be dynamically created, so I can't just explicitly make 10 or however many calls to the constructor. I don't know in advance how large the array must be.

1
  • class Waiter; here is bad , Waiter.h should do class Waiter; at least. Commented Jul 14, 2014 at 1:08

3 Answers 3

1

One option is to use placement new:

Table* tables = static_cast<Table*>(new char[sizeof(Table) * count]);
for(int i = 0; i < count; i++) new(&tables[i]) Table(tblid[i], mseats[i]);
Sign up to request clarification or add additional context in comments.

Comments

0

You can use a placement new in this particular situation, but do not forget to manually destruct your objects, and deallocate the raw memory with operator delete[] : (If you don't, your program will have undefined behavior)

Here is a minimal example of a placement new with array objects:

#include <new>

class MyClass
{
    public:
        MyClass(int i) : p(i) {}
    private:
        int p;
};

int main(int argc, char** argv) {

  // Allocate a raw chuck of memory
  void* buff10 = operator new[](sizeof(MyClass) * 10); 

  MyClass * arr = static_cast<MyClass*>(buff10);

  // Construct objects with placment new
  for(std::size_t i = 0 ; i < 10 ; ++i)
    new (arr + i) MyClass(i);

  // Use it ...

  // Then delete :

  for(std::size_t i = 9 ; i >= 0 ; --i)
      arr[i].~MyClass();

  operator delete[] (arr);

  return 0;
}

Comments

0

It's not possible to do this with new. But you should not be using new anyway. Use vector instead. Before C++11 it can't really cope with a const member, but in C++11 you have some options:

std::vector<Table> table = {
     { 1, 1 }, {2, 2}, {3, 3}, /* etc. */ };

Or you can add one by one:

std::vector<Table> table;
table.emplace_back( Table(1, 1) );
table.emplace_back( Table(2, 2) );

Since your class contains a const that makes it non-copyable. However it is still MoveConstructible.


Note: It probably makes things a lot easier here if you don't have a const class member, just keep it private and don't change it.

Also, depending on what you do with order and waiter, the default move constructor might not do the right thing. If these point to resources which are "owned" by the table then you will have to either manage these resources properly, or write your own a move constructor.

4 Comments

Unfortunately, this is a homework assignment, and the variable being constant was part of the original assignment. The assignment also stipulates that vectors are not allowed. If I were doing this from scratch it'd be wayyyyy less complicated.
Combining that with the stipulations "array size not known at compile-time", there is no solution other than placement new. Have you covered placement new in class? It seems unlikely to me that a course would ban vectors and expect placement new to be used instead. (It is common -- although still dreadful -- for C++ courses to require you to use C-style arrays instead of C++-style arrays, but this would be another level of pale)
Is it possible that you're misunderstanding the requirement for maxSeats to be const ?
the assignment was given in the form of a zip file of incomplete header and class files, with commented instructions on what to do to complete them. "const maxSeats" was something the professor added, along with an explanation of how to assign a value to it in the constructor, so it definitely wasn't a mistake

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.