【问题标题】:How to access an enum inside sub-class via object of main-class type?如何通过主类类型的对象访问子类内的枚举?
【发布时间】:2018-12-16 15:42:54
【问题描述】:

正如这个问题的标题中提到的,有没有语法可以做到这一点?

class Food : public Edible {
public:
    class Fruit : public FruitBase { //note: Fruit must be a class and a subclass of Food.
    public:    
        enum Type {                  //note: Type must be inside Fruit and must be a plain enum.(not enum class)
            APPLE,
            GRAPES,
            ORANGE,
        };
        //...
    };
    enum { CAKE, CHOCOLATE };
    //...
};

void func(){
    Food snack;
    //...
    auto typeA = snack.Fruit::APPLE;    //<---this is syntax error.
    auto typeG = snack.GRAPES;          //<---also syntax error. 
    auto typeO = Food::Fruit::ORANGE;   //<---this is OK, but not my target.

    auto typeC = snack.CAKE;           //<---this is OK.

    //...


}

我更喜欢typeG 的语法。我的第二个偏好是typeA。我目前在我的代码中使用typeO,但我需要从对象snack 而不是类Food 访问这些枚举常量。由于typeC 是可能的,我希望还有一种方法可以在子类中的枚举上执行此操作。

【问题讨论】:

  • 这样做能解决什么问题?
  • @JamesPoag 感谢您的链接。但是在我提出问题的项目部分,我们决定选择普通枚举。我们对其进行了研究并权衡了优缺点。但是在我们的项目中有一部分我们使用enum class。建议我们不要只关注互联网上的best practices 信息并自行确认,哪个更好用于特定类型的情况/问题。
  • @Nicky,很抱歉没有公开我的代码的更多细节。这是公司项目的一部分。问题是这样的:Fruit 子类名称存在于几个彼此不连接的 Food 类(具有不同的类名称)上。所以Fruit 子类是我们使用的数据结构的约定。 Fruit::Type 用作在函数中传递的参数。每次我们传递Fruit::Type 对象,目前,我们还指定Food,所以它是void testFunc(Food1::Fruit::APPLE)。但是有几个Food* 类。这实际上是关于代码的可维护性。
  • 我想我现在的问题的答案是No, there's no syntax support yet。但我想auto typeA = snack.Fruit::APPLE; 语法在 c++ 中得到支持很好。

标签: c++ enums


【解决方案1】:

类似这样的:

class Food {
public:
    class Fruit {      
    public:                       
        enum  Type {                                
            APPLE,
            GRAPES,
            ORANGE,
        };
        Type type;
    };
    Fruit fruit;

    enum class Foodies{ CAKE, CHOCOLATE };
    Foodies foodies;
};

void func() {
    typedef Food::Fruit::Type FruitType;

    Food snack; 
    auto typeA = snack.fruit.type = FruitType::APPLE;
}

【讨论】:

    【解决方案2】:

    更新

    您可以在Food 内创建Fruit 的实例,这样您就可以访问Food 内的Fruit 的成员。像这样:

    class Food : public Edible 
    {
    public:
        class Fruit : public FruitBase 
        { 
        public:
            enum Type{ APPLE, GRAPES, ORANGE };
        };
        static Fruit fruit; // -> this is what I was talking about
    
        enum { CAKE, CHOCOLATE };
    };
    
    
    int main()
    {
        Food food;
        auto apple = food.fruit.APPLE; // this is not so different of your 'typeG'
    }
    

    现在关于Fruit 需要是Food 的子类,但Fruit 已经是FruitBase 的子类,所以多重继承是另一个问题,也许this 可以帮助你。

    为什么不只使用这样的继承:

    #include <iostream>
    
    class Fruit 
    {
    public:
        enum Type { APPLE, GRAPES, ORANGE };
    };
    
    class Food : public Fruit
    {
    public:
        enum Foods { CAKE, CHOCOLATE };
    };
    
    int main()
    {
    
        Food food;
        auto apple =  food.Type::APPLE;
    }
    

    如果你真的更喜欢typeG,你可以让enum Type类Fruit的范围 像这样:

    #include <iostream>
    
    class Fruit 
    {
    public:
        enum { APPLE, GRAPES, ORANGE };
    };
    
    class Food : public Fruit
    {
    public:
        enum Foods { CAKE, CHOCOLATE };
    };
    
    int main()
    {
    
        Food food;
        auto apple = food.APPLE;
    }
    

    【讨论】:

    • 我忘了提到Food 是某个FoodBase 类的派生类。并且Fruit 必须是Food 的子类。我会编辑我的问题。感谢您的回答!
    • 我不喜欢在 Food 类上添加额外的字节(Fruit)只是为了添加一种访问这些枚举的方法。 Fruit 在我们的例子中包含很多字节。我测试了您的代码,可以通过将static const 添加到Fruit 实例来实现。为了避免创建Fruit 的实例(即使它是一个静态常量对象),我尝试了static const Fruit::Type fruit;,但这需要枚举在类/结构中才能工作。 struct Type { enum { APPLE, GRAPES, ORANGE }; };
    • 对不起,我忘了把 static 放在 Fruit 前面。使用嵌套类的最佳方法是 auto typeO = Food::Fruit::ORANGE; 而不实例化嵌套类。 look this
    猜你喜欢
    • 2016-03-06
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    相关资源
    最近更新 更多