繁体   English   中英

具有相同名称的枚举和类成员函数

[英]Enum & class member function with the same name

在我的工作场所强制执行的特定编码标准中,类中的访问器方法遵循特定的命名约定。 对于任何给定的成员变量,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() ,但我很想知道人们可以提出的其他解决方案。

您可以添加enum前缀以显式引用枚举类名,而不是函数名。

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
};

注意:上面的代码在g ++下工作,但在Visual Studio中有问题。 VS似乎不适用于范围枚举。 我们可以使用无范围的枚举(不带class关键字)。

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

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

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

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

我个人更喜欢用小写字母启动成员函数,而只用大写字母启动静态(成员)函数。 如果有一个真正的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;
};

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

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

enum class ENumber
{
    One, Two, Three
};

通过这种方式,它还可以帮助您快速识别出您在这里处理枚举,而不是类或函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM