【问题标题】:C++: Enum definition in class after usageC++:使用后类中的枚举定义
【发布时间】:2023-03-15 10:45:01
【问题描述】:

编译器是否有一种通用的方式来处理类中的枚举定义,例如,在private: 中使用枚举但之后在public: 部分中定义它是否可行?

代码示例:

class MyClass{
private:
  myEnum myMember;

public
  enum myEnum { A, B, C };

}

使用 gpp 似乎可以工作,但这是正确的用法吗?

【问题讨论】:

  • 枚举将是未定义的。
  • 我认为像这样混合隐私修饰符是一个糟糕的主意。这是一种糟糕的风格,不清楚,而且没有多大意义。你为什么想做这个?这不只是糟糕的风格吗?此类问题是否应该有值得考虑的答案?
  • 什么是gpp?如果您的意思是cpp 预处理器,它会让很多无效的C/C++ 程序通过。例如:This is not a valid C/C++ program!
  • @BigBadWolf 请显示可以编译的代码。您的代码将无法编译,因为在编译类的私有部分时未定义标识符 myEnum。
  • @Cinch 混合隐私修饰符(像这​​样和一般)是优秀的风格,使意图更清晰并且非常明智,时期。

标签: c++ class enums nested


【解决方案1】:

你需要反过来做

class MyClass{
 public:
  enum myEnum { A, B, C };

 private:
  myEnum myMember;
};

所以你在使用之前定义了枚举。但是,将枚举的定义公开,但将其存储在私有中是可以的 - 您可能不希望用户能够直接写入 myMember,但您希望他们了解类函数返回时的含义myEnum

【讨论】:

    【解决方案2】:

    如果要正确编写类,它至少会编译

    class MyClass
    {
    public:
      enum myEnum { A, B, C };
    
    private:
      myEnum myMember;
    };
    

    那么类中有两个成员。第一个是类型的定义

      enum myEnum { A, B, C };
    

    而且它是公开的。 第二个是 enum myEnum 类型的数据成员 myMember 的定义,它是私​​有的。

    所以类的用户可以使用类型名称enum myEnum,而不能直接访问数据成员myMember

    当类型定义为私有但此类型的数据成员定义为公共时,这是一个更有趣的示例。例如考虑以下类定义

    class MyClass
    {
    private:
      enum myEnum { A = 10, B, C };
    
    public:
      myEnum myMember = A;
    };
    

    在这种情况下,您无法访问枚举名称。如果您将尝试以下程序

    #include <iostream>
    
    class MyClass
    {
    private:
      enum myEnum { A = 10, B, C };
    
    public:
      myEnum myMember = A;
    };
    
    int main() 
    {
        MyClass c;
    
        myEnum x = c.myMember;
        //MyClass::myEnum x = c.myMember;
    
        std::cout << x << std::endl;
    
        return 0;
    }
    

    你会得到一个编译错误。但是你可以通过替换来欺骗编译器

    myEnum x = c.myMember;
    

    auto x = c.myMember;
    

    以下程序将编译

    #include <iostream>
    
    class MyClass
    {
    private:
      enum myEnum { A = 10, B, C };
    
    public:
      myEnum myMember = A;
    };
    
    int main() 
    {
        MyClass c;
    
        auto x = c.myMember;
    
        std::cout << x << std::endl;
    
        return 0;
    }
    

    【讨论】:

    • 它可以编译,但你为什么要这样做?
    • @tobi303 我只是在讨论这两种方法的区别。
    • 好吧,我只是想问一下,除了“它可以编译”之外,它是否还有其他用途:P 说真的,我很想知道这种方法可以用于什么。对我来说,这看起来像是无缘无故地让它变得比必要的复杂,但也许(实际上很可能)我只是不明白这一点。
    • @tobi303 据我所知,第二种方法用于某些模板定义。但现在我不记得了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 2020-07-19
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多