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

时间:2021-04-24 03:13:01

I have those classes A and B and more..

我有A级和B级以及更多..

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

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

...

They all inheritate from the abstract parent class O which knows how to manage an Items collection and won't let the kids play around with it as they want..

它们都从抽象的父类O继承而来,它知道如何管理Items集合,并且不会让孩子们随心所欲地玩它。

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

What can I use as a structure for O::_items that could get all the stored Items allocated on the stack? It should be possible since its size is ultimately known at compile time, shouldn't it?

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

Put it anoter way: How could I make the informations *nbItems* find their way up to O::size in a fashion that let the compiler know they are still literal constants, even yet undefined in O?

换句话说:我怎么能让信息* nbItems *以一种让编译器知道它们仍然是文字常量的方式找到它们的方式,甚至在O中是未定义的?


PS: By the time O is written, I am obviously not aware of all the possible derived classes it may have one day.

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

2 个解决方案

#1


2  

You could have a base class O without the array:

你可以有一个没有数组的基类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() {}
};

Then an intermediate derived class:

然后是一个中间派生类:

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

And then have all your actual derived classes derive from an intermediate class:

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

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

#2


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) { }
}

Or templatize A to make it more flexible:

或者将A模板化以使其更灵活:

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

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

Note that you do need a virtual destructor in class O if you polymorphically treat A's as O's (means: you definitely will, unless you are absolutely 100% sure that you won't)!!!!

请注意,如果您将A的多态视为O,则确实需要在O类中使用虚拟析构函数(意思是:您肯定会,除非您完全100%确定不会这样做)!

#1


2  

You could have a base class O without the array:

你可以有一个没有数组的基类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() {}
};

Then an intermediate derived class:

然后是一个中间派生类:

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

And then have all your actual derived classes derive from an intermediate class:

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

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

#2


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) { }
}

Or templatize A to make it more flexible:

或者将A模板化以使其更灵活:

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

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

Note that you do need a virtual destructor in class O if you polymorphically treat A's as O's (means: you definitely will, unless you are absolutely 100% sure that you won't)!!!!

请注意,如果您将A的多态视为O,则确实需要在O类中使用虚拟析构函数(意思是:您肯定会,除非您完全100%确定不会这样做)!