使用基类中派生类的常量

时间:2014-08-28 09:18:11

标签: c++

我有以下设计:

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

最好的方法是什么?

3 个答案:

答案 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绝不会有无意义的解决方案,你可以避免使用模板。