常量大小的数组,在编译时已知..但仅在派生类中

时间:2014-07-20 09:28:14

标签: c++ arrays inheritance heap literals

我有这些课程AB以及更多..

class A : public O
{
    static const int _nbItems = 3;
    ...
};

class B : public O
{
    static const int _nbItems_mine_mine = 7800;
    ...
};

...

他们都继承自抽象父类O,其中知道如何管理Item集合,并且不会让孩子们随心所欲地玩耍..

class O
{
private:

    // The kids won't be able to access this structure directly for it is carefully updated
    Item _items[size];        

    // (I mean.. *truly*, look :)
    void update() // called by the clock
    {
       for(int i(0); i < size; ++i) /* things involving */ _items[i] /*, its environment etc.*/
    };

protected:

    // They may set their items this way only:
    void setItemNo(int id, BuildInformation const& buildInfo)
    {
        /* 
         * check whether or not the item has already been added..
         * perform everything that must be done to welcome a new item..
         * well.. 'so many things the kids do not need to be aware of.
         */

        // and then:
        _items[id] = Item(buildInfo);

    };

   // .. retrieve information about the current state of their items this way only:
   SomeInformation getItemState(int id) const {return _items[id].currentState();};

   // .. and eventually change some of their properties this way only:
   void setItemProperty(int id, Property const& newProperty)
   {
     /* checks, updates, eventual repercussions on other items and the environment */
     _items[id].setProperty(newProperty);
   };
};

我可以使用什么作为O::_items的结构来获取在堆栈上分配的所有存储的Item ?它应该是可能的,因为它的大小最终在编译时是已知的,不应该吗?

换一种说法:我怎样才能使信息*nbItems*以一种让编译器知道它们仍然是文字常量的方式找到自己的方式O::size,甚至在{{1}中未定义}}?


PS:写O时,我显然不知道有一天可能有的所有派生类。

2 个答案:

答案 0 :(得分:2)

你可以有一个没有数组的基类O

class O
{
    virtual size_t size() const = 0;
    virtual Item * data() const = 0;

    void update()
    { 
        for (Item * p = data(), * e = p + size(); p != e; ++p)
        {
            // use *p
        }
    }

public:
    virtual ~O() {}
};

然后是一个中间派生类:

template <size_t N> class OWithArray : public O
{
public:
    static size_t const nItems = N;
private:
    Item items[N];
    virtual size_t size() const { return nItems; }
    virtual Item * data() const { return items; }
};

然后让所有实际派生类派生自中间类:

class A : public OWithArray<3>
{
    // ...
};

答案 1 :(得分:1)

class O {
  private:
     Item* items;
     unsigned int number_of_items

  protected:
     O (Item* itemsstorage, unsigned int n_items)
     : items (itemsstorage), number_of_items (n_items) { ... }

  // you'll probably need something like the following
  // make it private rather than using "= delete" prior to C++11
     O & operator = (const O &) = delete;
     O (const O &) = delete;
     O (O &&) = delete;

  public:
     virtual ~O () { }
}

class A : public O {
  private:
     enum { howManyItems = 3 };
     Item allMyItems [howManyItems];

  public:
     A () : O (allMyItems, howManyItems) { }
}

或者对A进行模板化以使其更加灵活:

template<unsigned int N>
class A : public O {
  private:
     Item allMyItems [N];

  public:
     A () : O (allMyItems, N) { }
}

请注意,如果您将O多态地视为A,则执行需要在班级O中使用虚拟析构函数(意思是:你肯定会,除非你绝对100%肯定你赢了)!!!!