用常量变量声明一个对象数组

时间:2014-07-14 00:58:32

标签: c++ arrays pointers object

我有一个包含以下头文件的表对象:

#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

在我的main函数中,我需要声明一个表数组。但是当我写,例如,Table * table = new Table [10]时,数组的每个元素都在构造函数中调用默认参数,并且每个表最终都有一个恒定的最大座位值0.我需要能够单独调用每个构造函数,使其具有maxSeats的不同值。

到目前为止,我能够提出的唯一解决方案是声明一个指向表对象的指针数组,然后分别实例化每个对象。这部分工作,但上面代码中提到的Waiter类接受一个Tables数组作为参数,如果它传递了一个Table指针数组将无法工作。

我可以执行哪些过程来结束具有不同maxSeats常量变量值的Table对象数组?

还有一点需要澄清:数组必须动态创建,因此我不能只显式地对构造函数进行10次或多次调用。我事先并不知道数组必须有多大。

3 个答案:

答案 0 :(得分:1)

一种选择是使用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]);

答案 1 :(得分:0)

使用new无法执行此操作。但是你不应该使用new。请改用vector。在C ++ 11之前,它无法真正处理const成员,但在C ++ 11中你有一些选择:

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

或者您可以逐个添加:

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

由于您的类包含const,因此无法复制。但它仍然是MoveConstructible。


注意:如果您没有const班级成员,可能会让事情变得更加轻松,只需保留private并且不要更改它。

此外,根据您对orderwaiter所做的操作,默认的移动构造函数可能无法做正确的事情。如果这些指向由表“拥有”的资源,那么您将必须正确地管理这些资源,或者编写自己的移动构造函数。

答案 2 :(得分:0)

您可以在这种特殊情况下使用placement new,但不要忘记手动销毁您的对象,并使用operator delete[]取消原始内存:(如果您不喜欢#39; t,你的程序将有未定义的行为)

以下是数组对象的新位置的最小示例:

#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;
}