我有以下设计:
class PureVirtual
{
unsigned m_count; // = 0 in constructor
void register() {assert(m_count + 1 <= MAX); m_count++;};
};
class A : public PureVirtual
{enum {MAX = 42}};
PureVirtual
除了MAX
之外不知道。
我使其工作的方式是创建m_max
成员PureVirtual
,然后将其初始化为一个愚蠢的值(因为如果成员未初始化,gcc
会发出警告构造函数),然后在A
的构造函数中设置它。最好的&#34;部分原因是它不能成为const
。
最好的方法是什么?
答案 0 :(得分:8)
在m_max
中定义PureVirtual
成员:
const unsigned m_max;
在PureVirtual
构造函数中初始化它:
PureVirtual(unsigned max) : m_max(max) {}
并从继承类的构造函数中传递您想要的值:
A() : PureVirtual(42) {}
答案 1 :(得分:4)
您的设计已损坏,因为基类需要存储在后代类中的信息。请尝试使用政策或遏制:
template <typename Policy>
class PureVirtual
{
enum { MAX = Policy::MAX };
unsigned m_count; // = 0 in constructor
void register() {assert(m_count + 1 <= MAX); m_count++;};
};
答案 2 :(得分:3)
使用虚函数可以更好地解决这个问题:
#include <cassert>
class PureVirtual {
int m_count;
public:
virtual int max() = 0;
void register_() {
assert(m_count + 1 <= max());
m_count++;
};
};
class A : public PureVirtual {
public:
int max() {
return 42;
}
};
int main() {
A a;
for (int i = 0; i < 43; ++i) {
a.register_();
}
}
max
如果要隐藏,可以加以保护。要更改max的值,只需在派生类中重写它即可。这个解决方案的优点是max绝不会有无意义的解决方案,你可以避免使用模板。