When/why to make function private in class?

穿精又带淫゛_ 提交于 2019-11-28 08:18:25

You should make a function private when you don't need other objects or classes to access the function, when you'll be invoking it from within the class.

Stick to the principle of least privilege, only allow access to variables/functions that are absolutely necessary. Anything that doesn't fit this criteria should be private.

I usually make the helper functions private. But what is helper seems to be vague. So let me give you an example. Suppose you've the following class Sample; it exposes few public functions, one of them, say, is DoWork(). This function takes one parameter. But it doesn't assume that the parameter will always be valid, so it first checks the validity of parameter for which it has lots of code in the beginning of the function. Something like this:

class Sample
{
   public:
      void DoWork(SomeClass param)
      {
               /*
                *lots of code related to validation of param
                */  

                //actual code that operates on the param 
                //and other member data IF the param is valid
      }
};

Since you've written lots of code related to validation of the param, it makes the function cumbersome, and difficult to read. So you decided to move this validation code to function say, IsValidParam(), and then you call this function from DoWork() passing the parameter param to it. Something like this:

class Sample
{
   public:
      void DoWork(SomeClass param)
      {       
            if ( IsValidParam(param))       
            {
                //actual code that operates on the param 
                //and other member data IF the param is valid
            }
      }
};

That looks cleaner, right?

Okay, you've written IsValidParam() somewhere in the class, but the question you face now is, would you make this function public? If this function is used only by your other functions like DoWork(), then making IsValidParam() public doesn't make sense. So you decided to make this function private.

class Sample
{
   public:
      void DoWork(SomeClass param)
      {       
            if ( IsValidParam(param))       
            {
                //actual code that operates on the param 
                //and other member data IF the param is valid
            }
      }
  private:
      bool IsValidParam(SomeClass param)
      {
          //check the validity of param.
          //return true if valid, else false.
      }
};

Functions of this kind (IsValidParam) should be private. I call these functions helper functions.

Hope this explanation helps you!

One of the founding principals of OOP is encapsulation. This is where functionality for how an object works is kept internal to that object. The idea is that it's easier for code to use an object if it doesn't need to know how it works. Kind of like buying a microwave--you just need to know how to use it and not how it works.

The same approach should be taken with OOP. Keep everything needed to maintain the object private. Make only what is needed to fully use the object public.

If you are designing a class - considering the way client code should use it - then you will inevitably derive an interface consisting of public and perhaps protected members.

private members are functions and data that supports and enables those public/protected members. private functions should factor and/or modularise/structure the code needed by the non-private members, making their implementation less redundant and easier to understand.

Summarily, you make a member private if it's not intended for direct use by client code, and only exists to support the non-private members.

How purist do you want to be? :)

The proper answer to this question is related to the maintenance of invariants. The right way to do this is rather complicated.

In your base class you define public methods to provide the whole of the access to the class. All these methods must be concrete. The key thing here is that the public invariants are assumed to hold before and after calling these functions. These functions must never call each other, they call only protected and private methods. These functions should be axiomatic: they should be a fairly minimal set required to capture the desired semantics.

Most calculations which can be done using these methods should be global or at least public static members.

You also provide pure virtual methods which are hooks to implement the details depending on the representation in derived classes. Virtual functions in the base should be private. The usual advice here (public) is completely wrong. Virtual functions are implementation details. One exception: the virtual destructor must be public.

Private helper functions can also be put in the base.

It may be useful to have protected methods in the base too: these will call the private helpers or virtuals. As above: protected methods should never call protected or public methods. Protected functions maintain a weaker invariant than the public one before and after each call.

Private functions usually maintain very weak invariants.

The reason for this strict hierarchy is to ensure the object invariants are maintained correctly.

Now, in a derived class you provide an implementation. Ideally, the virtual functions here would be invisible, a stronger condition than merely private. These virtual functions should not be called at all in the derived class. The only permitted access is via protected functions of the base.

All methods of derived classes including the destructor should be private. Constructors must be public, but they're not methods of the class.

In order to fully understand these rules you must think carefully about invariants. The public invariants can be assumed to hold prior to calling a public method and are required to hold after it is finished. Therefore you cannot call such functions from inside the class nor any class derived from it, because those functions are used to modify the representation in-between the start and end of a public function, and so inevitably break the public invariants: that's why they must not call the public functions.

The same argument applies to protected functions: functions can only call functions with weaker invariants.

Virtual functions are always called by the public from the base class public wrappers to ensure the sequencing of operations, which breaks public invariants, is never interrupted by returning to the public with a broken invariant. The set of virtuals themselves represent the invariant structure any representation must have. By doing this all manipulations of the representation to perform calculations for public clients can be abstracted into the base.

In practice, these rules are not usually followed because they would often generate trivial wrappers and that's a lot of extra code to write and maintain. So virtual functions often end up being public, even when this is completely and utterly wrong in principle.

Before creating a function or class we should understand scope of that function or class whether it is Globally or Locally.

eg:"ConnectionString ()". Every database connection needs "ConnectionString () " so its declared Public .

private: only used by this class, not used by other classes nor derived classes.
protected: used by this class and maybe derived classes, but not used by other classes.
public: used by other class, this class, and derived class.

It's hard to choose between private and protected. So I always make a function protected if there is 1% chance that derived classes may need it.

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