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 Item
s 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 Item
s 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%确定不会这样做)!