[英]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函数,我也更喜欢将它们标记为setNumber
和getNumber
。
仅这一点就会使代码看起来像这样:
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.