公共静态常量变量是否破坏了封装意识形态
Does a public static const variable break the encapsulation ideology?
我似乎总是在决定一个应该static
和const
的类中的值应该是公共的还是私有的,使用静态的公共方法进行访问。
class DeepThought
{
public:
static const int TheAnswer = 42;
};
对:
class DeepThought
{
public:
static int GetTheAnswer() { return TheAnswer; }
private:
static const int TheAnswer = 42;
};
我想用第一种方式来做,但在我内心深处的某个地方,感觉它打破了封装,即使它是一个恒定的值。第二种方式似乎并没有真正向表格添加任何东西,并且不必要地使代码混乱。
所以我问,这两种选择有什么根本性的问题吗?如果有,那是什么?
在纯粹的理论意义上,第二种选择更正确。在实际意义上,我同意你的看法 - 用 getter 函数包装常量值是没有用的,无论如何都会被编译器删除。
根据我的经验,有时更简单的方法更好,即使它在某种程度上违反了 OOP。
最后一点 - 我们曾经为此使用枚举:
enum CONSTS
{
TheAnswer = 42,
};
语义上并不等效。更喜欢第一个,因为它产生一个完整的常量表达式,可用于数组边界、非类型模板参数、大小写表达式等。
int a[DeepThought::TheAnswer]; // ok
int b[DeepThought::GetTheAnswer()]; // broken
你应该考虑为什么OOP"意识形态"说不要暴露变量,只暴露getter。 通常的论点是因为在将来的某个时候,您可能需要使对该变量的访问执行更复杂的操作。 但是这种情况的几率一开始就很小,当你谈论一个常数时,这种可能性会变得更小。
我会继续将常量公开为常量。 但是,我通常也会在当前不需要getter时继续公开变量。 Python团队会称之为"你不需要它"原则的应用。
很明显:
class DeepThought
{
public:
static int GetTheAnswer() { return 42; }
};
你也可以使用第一个。考虑一下 - 你要投入什么逻辑来GetTheAnswer()
?您无法在不破坏其接口注意事项的情况下更改其签名或静态事实。这意味着,除非你要开始制作非常恒定的全局变量,这将是非常糟糕™的,否则你可以放入GetTheAnswer()
中,你不能放入TheAnswer
分配到的constexpr中。
此外,你可以用GetTheAnswer()
做什么是有限制的,例如,首先你可以获取常量的地址,而用GetTheAnswer()
,你不能,即使你应该能够这样做是相当合理的。
这样的这些常量基本上是隐藏的单例模式。只有一个常量实例可用。这将是此类代码的正常演变:
class DeepThought {
public:
static const int i=10;
void f() { std::cout << i; }
};
然后你需要更改变量以在运行时更改,它将变成这样:
class Singleton {
static Singleton &get() { static Singleton s; return s; }
int get_i() const { return i; }
};
class DeepThought {
public:
void f() { std::cout << Singleton::get().get_i(); }
};
然后在某些时候,你会想要这个常量的多个实例,它会变成这样:
struct Data
{
int i;
};
class DeepThought {
public:
DeepThought(Data &d) : d(d) { }
void f() { std::cout << d.i; }
private:
Data &d;
};
int main() { Data d; DeepThought dt(d); dt.f(); }
在代码的演变过程中,它会发生很大的变化,如果你有大量这样的代码,那么进行更改可能需要大量的努力。
- 在提升multi_index容器中,是否定义了"default index"?
- #定义c-预处理器常量..我做错了什么
- wxWidgets mac剪贴板在3.1.3上坏了?
- 计时器坏了或者其他什么的
- boost::p rocess::env 在 ubuntu 19.04 上坏了?
- std::regex 是否保证了最坏情况下的时间复杂度?
- 课堂上的一行,使整个应用程序坏了. 0xC000005错误
- C++编译器在封装行为上存在分歧 - 哪一个做对了?
- 假设钻石继承打破了C++的封装是否正确?
- 期望在模拟对象上调用了某个方法.它会破坏封装吗?
- SFML sf::Text::setFillColor 坏了,还是我做错了什么
- 非好友、非成员函数增加了封装
- 开关内的案例不停地循环,即使我坏了
- 这里是否违反了封装的概念
- 溪水变坏了
- 我最基本的c++程序坏了,我不知道为什么
- 我的电脑怎么坏了?
- 条件评估是否优化?这个代码坏了吗
- 公共静态常量变量是否破坏了封装意识形态
- 地图:坏Ptr,即使找到了钥匙