在派生类中重写枚举值

时间:2019-07-16 14:15:25

标签: c++ enums

我有一个class A,其中使用了一些枚举,例如:

enum DataType
{
    First,
    Second,
    Third
}

随后,他们被分配了一些在代码中使用的值。

现在,我必须编写与class B非常相似的另一个class A,为此我计划制作一个class Parent并派生class A和{ {1}}。但是,我想在两个类中重用class B

问题在于,enum DataTypeenum的这些class A值应该不同。

对于class B

class A

对于enum DataType { First = 1, Second = 2 ... }

class B

想到的一种幼稚方法是在两个类中都定义一个虚函数,它们都具有enum DataType { First = 18, Second = 19 ... } ,因此,除了使用枚举,我还必须调用虚函数并使用其返回的内容。 / p>

但是,还有更好的方法吗?通过使用一些我不知道的继承属性?

4 个答案:

答案 0 :(得分:1)

A和B的数据类型是不同的类型,因此Parent类必须是模板:

http://geo.ma/).txt

请注意,我使用了enum类而不是(旧式的)enum,以避免陷入enum值的歧义。

答案 1 :(得分:1)

一种方法:

template<int EnumBegin>
struct Parent {
    enum DataType {
        First = EnumBegin,
        Second, // == First + 1
        Third   // == Second + 1
    };
};

struct A : Parent<0> {};
struct B : Parent<10> {};

int main() {
    std::cout << A::Second << '\n'; // Outputs 1.
    std::cout << B::Second << '\n'; // Outputs 11.
}

答案 2 :(得分:1)

一个简单的解决方案是在每个成员中定义一个enum DataType。这不会带来运行时或存储开销。但是在这种情况下,行为是静态的。用户只能基于静态类型访问枚举。如果枚举值遵循与示例相同的模式,则可以生成枚举,甚至可以使用模板生成整个类。

您建议使用动态方法:使用虚函数。这有一些开销,但是提供了运行时多态性。在这种情况下,用户可以访问特定于动态类型的枚举,而无需知道该类型是什么。

这两种方法甚至可以结合在一起使用,从而使两者兼具。

答案 3 :(得分:0)

我只是将派生类的类型发送给父类函数:

// parent not templated!
struct Parent {

    // with this pattern, stuff1 could be virtual:
    // virtual void stuff1() = 0;

protected:
    // static because we can access private
    // member through the self object
    template<typename T>
    static void stuff1_impl(T const& self) {
        auto value = /* get the switched on value */;

        switch(value) {
        case T::DataType::First:
            // things for the case1
            break;
        case T::DataType::Second:
            // things for the case1
            break;
        }
    }
};

然后在派生类中:

struct A : Parent {
    enum struct DataType {
        First = 1, Second
    };

    //               v---- if virtual, add override
    void stuff1() /* override */ {
        stuff1_impl(*this);
    }
};

struct B : Parent {
    enum struct DataType {
        First = 10, Second
    };

    //               v---- if virtual, add override
    void stuff1() /* override */ {
        stuff1_impl(*this);
    }
};

此模式避免模板化整个基类,并且您仍然可以使用虚拟多态性。您只需在受保护的部分中对需要枚举的部分进行模板化。

Live example