Does a public static const variable break the encapsulation ideology?

笑着哭i 提交于 2020-07-09 12:14:26

问题


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?


回答1:


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



回答2:


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



回答3:


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.




回答4:


There is the obvious:

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



回答5:


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.




回答6:


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.



来源:https://stackoverflow.com/questions/5922455/does-a-public-static-const-variable-break-the-encapsulation-ideology

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!