public static const 变量是否破坏了封装思想?

发布于 2024-11-06 07:47:09 字数 467 浏览 4 评论 0原文

我似乎总是在决定类中应该是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

你怎么这么可爱啊 2024-11-13 07:47:09

从纯粹的理论意义上来说,第二种选择更为正确。从实际意义上来说,我同意你的观点——用 getter 函数包装常量值是没有用的,无论如何都会被编译器删除。

根据我的经验,有时更简单的方法更好,即使它在某种程度上违反了 OOP。

最后一点 - 我们曾经使用枚举来实现这一点:

enum CONSTS
{
    TheAnswer = 42,
};

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:

enum CONSTS
{
    TheAnswer = 42,
};
我三岁 2024-11-13 07:47:09

它们在语义上并不等同。更喜欢第一个,因为它产生一个整型常量表达式,可以在数组边界、非类型模板参数、case 表达式等中使用。

int a[DeepThought::TheAnswer];      // ok
int b[DeepThought::GetTheAnswer()]; // broken

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.

int a[DeepThought::TheAnswer];      // ok
int b[DeepThought::GetTheAnswer()]; // broken
不疑不惑不回忆 2024-11-13 07:47:09

您应该考虑为什么 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.

無心 2024-11-13 07:47:09

有一个显而易见的事实:

class DeepThought
{
public:
    static int GetTheAnswer() { return 42; }
};

There is the obvious:

class DeepThought
{
public:
    static int GetTheAnswer() { return 42; }
};
你是我的挚爱i 2024-11-13 07:47:09

您也可以使用第一个。考虑一下 - 您要在 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 in GetTheAnswer() that you can't put in the constexpr which TheAnswer 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 with GetTheAnswer(), you can't, even though it's pretty reasonable that you should be able to.

浅笑轻吟梦一曲 2024-11-13 07:47:09

这些常量基本上都是隐藏的单例模式。可用常量只有一个实例。这将是此类代码的正常演变:

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

在代码的演变过程中,它会发生很大的变化,如果你有大量这样的代码,进行更改可能需要花费大量的精力。

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:

class DeepThought {
public:
   static const int i=10;
   void f() { std::cout << i; }
};

Then you'll want to change the variable to change on runtime, it'll become like this:

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

Then at some point you'll want more than one instance of the constant and it'll become like this:

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文