用枚举编译时间多态性

时间:2015-02-01 18:00:50

标签: c++ c++11 inheritance enums polymorphism

所以,这些问题与enum继承有关,我在这里看到了很多主题,其中描述了如何编写支持继承的枚举,但我认为这不是我的情况。

我找到了一些我想做的东西。所以我的想法是我有类,让它成为OpenGL纹理类(实际上是它),并且有一个枚举代表纹理中一个属性的所有可能值。

class Texture
{
    public:
        enum Filter
        {
            LINEAR   = 1,
            BILINEAR = 2,
            ANISOTROPIC = 3
        };

    public:
        Texture(Filter _filter)
            : filter(_filter) 
        { }

    private:
        Filter filter;
};

继承它的类。必须重新定义派生类中的枚举,但我可以在基类的构造函数中进一步使用:

class Texture2d : public Texture
{
    public:
        enum Filter
        {
            LINEAR   = 1,
            BILINEAR = 2
        };

    public:
        Texture2d(Filter _filter)
            : Texture(_filter)
        { }
};

但是,当然,这不起作用,因为新创建的FilterTexture2d::Filter,而不是Texture::Filter

我尝试使用这样的enum class

class Texture
{
    public:
        enum class Filter;

    public:
        Texture(Filter _filter)
            : filter(_filter)
        { }

    private:
        Filter filter;
};

class Texture2d : public Texture
{
    public:
        enum Filter
        {
            LINEAR = 1,
            BILINEAR = 2
        };

    public:
        Texture2d(Filter _filter)
            : Texture(_filter)
        { }
};

但这是一个非常愚蠢的想法。我想,如果我只想扩展枚举,我会写一些类包装器,但我也需要缩小枚举。所以问题是,如何使这个东西在编译时工作?这是主要问题 - 在编译时使这项工作。还有一个问题:实际上尝试做这些事情还可以,或者我必须查看我的应用程序的架构?

(所有答案将不胜感激)

2 个答案:

答案 0 :(得分:0)

我没有看到您的代码存在问题 您只需在Texture2d的构造函数中添加强制转换。

Texture2d(Filter _filter) // no Texture::Filter
    : Texture(static_cast<Texture::Filter>(_filter))
{ }

Texture t1(Texture::LINEAR);           // WORKS
Texture t2(Texture::BILINEAR);         // WORKS
Texture t3(Texture::ANISOTROPIC);      // WORKS

Texture2d t4(Texture2d::LINEAR);       // WORKS
Texture2d t5(Texture2d::BILINEAR);     // WORKS
Texture2d t6(Texture2d::ANISOTROPIC);  // ERROR

这是因为Texture2d::ANISOTROPIC被解释为Texture::ANISOTROPIC,因为不存在Texture2d::Filter::ANISOTROPIC

由于Texture2d个构造函数都没有接受Texture::Filter,因此会导致错误。

答案 1 :(得分:0)

枚举没有继承 - 所以扩展/减少的想法是不可能的。您可以做的是在Texture2d之间提供转换方法:

class Texture2d : public Texture {
public:
    enum class Filter {
        LINEAR, BILINEAR
    };

    Texture2d (Filter f)
    : Texture(convert(f))
    { }

private:
    Texture::Filter convert(Filter f) {
        switch(f) {
        case Filter::LINEAR: return Texture::Filter::LINEAR;
        // etc.
        default: 
            // ? Maybe throw? 
     }
};

这样就可以指定每个子类中的有效枚举列表。如果你通常想要允许相同的那些,它可能是重复的。

相关问题