public static const 变量是否破坏了封装思想?
我似乎总是在决定类中应该是 static 和 const 的值应该是公共的还是私有的,并使用静态公共方法进行访问。
class DeepThought
{
public:
static const int TheAnswer = 42;
};
与:
class DeepThought
{
public:
static int GetTheAnswer() { return TheAnswer; }
private:
static const int TheAnswer = 42;
};
我想用第一种方式来做,但在我内心深处的某个地方感觉它打破了封装,即使它是一个恒定的值。第二种方法似乎并没有真正向表中添加任何内容,并且不必要地使代码变得混乱。
所以我问,这两种选择是否存在根本性错误?如果有,又是什么?
I always seem to struggle with the decision of whether a value in a class which should be static
and const
should be public or private with a static public method for access.
class DeepThought
{
public:
static const int TheAnswer = 42;
};
versus:
class DeepThought
{
public:
static int GetTheAnswer() { return TheAnswer; }
private:
static const int TheAnswer = 42;
};
I want to do it the first way, but somewhere deep inside me feels like it breaks encapsulation even though its a constant value. The second way just seems like it doesn't really add anything to the table though and needlessly clutters up the code.
So I ask, is there anything fundamentally wrong with either choice and if so, what?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
从纯粹的理论意义上来说,第二种选择更为正确。从实际意义上来说,我同意你的观点——用 getter 函数包装常量值是没有用的,无论如何都会被编译器删除。
根据我的经验,有时更简单的方法更好,即使它在某种程度上违反了 OOP。
最后一点 - 我们曾经使用枚举来实现这一点:
In a purely theoretical sense, the second option is the more correct. In the practical sense, I agree with you - wrapping the constant value with a getter function is useless and will be removed by the compiler anyway.
In my experience, sometimes the simpler approach is better, even if it violates OOP somewhat.
And a final note - we used to use enums for this:
它们在语义上并不等同。更喜欢第一个,因为它产生一个整型常量表达式,可以在数组边界、非类型模板参数、case 表达式等中使用。
They aren't semantically equivalent. Prefer the first, because it yields an integral constant expression which can be used in array bounds, nontype template arguments, case expressions, etc.
您应该考虑为什么 OOP“意识形态”说不要公开变量,只公开吸气剂。通常的论点是因为您可能在将来的某个时候需要访问该变量来执行更复杂的操作。但这种可能性一开始就很小,当你谈论一个常数时,这种可能性会变得更小。
我会继续将常数暴露为常数。但是,当当前不需要 getter 时,我通常也会继续公开变量。 Python 团队将其称为你不需要它原则的应用。
You should think about why the OOP "ideology" says don't expose variables, only getters. The usual argument is because you might, at some point in the future, need to make access to that variable do something more complicated. But the odds of this are small to begin with, and become even smaller when you're talking about a constant.
I would go ahead and expose the constant as a constant. But then I would also usually go ahead and expose variables when there is no current need for a getter. The Python crew would call this an application of the You Aren't Gonna Need It principle.
有一个显而易见的事实:
There is the obvious:
您也可以使用第一个。考虑一下 - 您要在
GetTheAnswer()
中放入什么逻辑?您无法在不破坏其接口注意事项的情况下更改它的签名或它是静态的事实。这意味着,除非您要开始创建非常量全局变量(这将是非常糟糕的™),否则您可以在GetTheAnswer()
中放入任何不能放入 constexpr 中的内容。TheAnswer
已分配给。此外,使用
GetTheAnswer()
可以执行的操作也有限制,例如,在第一个中,您可以获取常量的地址,而使用GetTheAnswer()
则可以不能,尽管您应该能够这样做是很合理的。You may as well use the first. Consider- what logic are you going to put in to
GetTheAnswer()
? You can't change it's signature or the fact that it's static without breaking it's interface considerations. This means that unless you're going to start making non-constant global variables, which would be Extremely Bad™, there's nothing you might put inGetTheAnswer()
that you can't put in the constexpr whichTheAnswer
is assigned to.Moreover, there are limits with what you can do with
GetTheAnswer()
, for example, in the first you could take the address of the constant and withGetTheAnswer()
, you can't, even though it's pretty reasonable that you should be able to.这些常量基本上都是隐藏的单例模式。可用常量只有一个实例。这将是此类代码的正常演变:
然后您将想要更改要在运行时更改的变量,它将变成这样:
然后在某一时刻您将需要该常量的多个实例,并且它将变成这样:
在代码的演变过程中,它会发生很大的变化,如果你有大量这样的代码,进行更改可能需要花费大量的精力。
these constants like this are basically hidden singleton pattern. There is only one instance of the constants available. This will be the normal evolution of such code:
Then you'll want to change the variable to change on runtime, it'll become like this:
Then at some point you'll want more than one instance of the constant and it'll become like this:
During the evolution of the code, it'll change quite much and if you have large amount of code like that, doing the changes could take large amount of effort.