Enum&具有相同名称的类成员函数

时间:2017-01-24 14:41:01

标签: c++ enums naming-conventions

在我的工作场所强制执行的特定编码标准中,类中的访问器方法遵循特定的命名约定。对于任何给定的成员变量,getter的名称相同,setter的前缀为Set。见下面的例子。

class Foo
{
public:
    int Number() const { return m_number; }
    void SetNumber(int number) { m_number = number; }

private:
    int m_number;
};

当我有一个同名的枚举时,这变得很古怪:

enum class Number
{
    One, Two, Three
};

class Foo
{
public:
    Number Number() const { return m_number; }
    void SetNumber(Number number) { m_number = number; }

private:
    Number m_number;
};

上面的示例将无法编译,因为在某些地方,编译器无法确定我是否引用了枚举名称或函数名称。因此,为了在不违反编码标准的情况下解决这个问题,我必须在模棱两可的地方使用::,我实际上是指枚举:

enum class Number
{
    One, Two, Three
};

class Foo
{
public:
    ::Number Number() const { return m_number; }
    void SetNumber(::Number number) { m_number = number; }

    void DoStuffWithNumber()
    {
        if (m_number == ::Number::One)
        {
            // Do stuff
        }
    }

private:
    Number m_number;
};

对于代码的读者来说这有点令人困惑,但是在某些上下文中必须完全限定枚举名称也有点烦人。这并不是一直都很简单。

这里有什么更合理的解决方法?显然我可以做一些事情,比如将访问者重命名为GetNumber(),但我很想知道人们可以提出的其他解决方案。

4 个答案:

答案 0 :(得分:2)

由于枚举可以采用一系列值,我会在这里使用复数:

enum class Numbers
//               ^
{
    One, Two, Three
};

这不是一种罕见的做法。例如,在Google C++ style guide中,他们使用以下枚举命名示例:

enum UrlTableErrors {
  kOK = 0,
  kErrorOutOfMemory,
  kErrorMalformedInput,
};
enum AlternateUrlTableErrors {
  OK = 0,
  OUT_OF_MEMORY = 1,
  MALFORMED_INPUT = 2,
};

答案 1 :(得分:2)

您可以添加switch (Integer.toString(account1) + "_" + Integer.toString(account2)){ case "1_1": case "2_1": } 前缀以显式引用枚举类名,而不是函数名。

enum
  

注意:以上代码在g ++下运行,但在Visual Studio中有问题。 VS似乎不适用于范围枚举。我们可以使用无范围的枚举(不使用enum class Number { One, Two, Three }; class Foo { public: enum Number Number() const { return m_number; } void SetNumber(enum Number number) { m_number = number; } private: enum Number m_number; // Number here refers to enum class, not function }; 关键字)。

答案 2 :(得分:1)

我个人更喜欢使用小写字母启动成员函数,而只使用大写字母启动静态(成员)函数。 如果有真正的getter和setter函数,我也希望将它们标记为setNumbergetNumber对。

仅这一点就会使代码看起来像这样:

enum class Number
{
    One, Two, Three
};

class Foo
{
public:
    Number getNumber() const { return m_number; }
    void setNumber(Number number) { m_number = number; }
private:
    Number m_number;
};

对于通过名为number的函数访问m_number的情况,我将返回一个引用(或const case中的const引用):

enum class Number
{
    One, Two, Three
};

class Foo
{
public:
    Number& number() { return m_number; }
    const Number& number() const { return m_number; }
private:
    Number m_number;
};

在这种情况下,您可能想要完全摆脱“命名函数”,只提供对话操作符。

答案 3 :(得分:0)

为什么不为你的枚举使用前缀?就像使用m_作为成员变量一样,您可以在枚举前加上E:

enum class ENumber
{
    One, Two, Three
};

这样它还可以帮助您快速识别您在此处理枚举,而不是类或功能。