C++ 何时/为什么在课堂上将函数设为私有?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4505938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:35:00  来源:igfitidea点击:

When/why to make function private in class?

c++oopclass-designprivate-methods

提问by Ramilol

When should i make a function privateand why is it good idea?

我什么时候应该创建一个函数private,为什么它是个好主意?

回答by Jacob Relkin

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

private当您不需要其他对象或类来访问函数时,当您将从类中调用它时,您应该创建一个函数。

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.

坚持最小特权原则,只允许访问绝对必要的变量/函数。任何不符合此标准的都应该是private.

回答by Nawaz

I usually make the helper functions private. But what is helperseems 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 firstchecks the validity of parameter for which it has lots of code in the beginning of the function. Something like this:

我通常制作辅助函数private。但是助手是什么似乎很模糊。所以让我给你举个例子。假设您有以下课程Sample;它公开了很少的公共功能,例如,其中之一是DoWork(). 这个函数接受一个参数。但是它并不假设参数总是有效的,所以它首先检查参数的有效性,它在函数的开头有很多代码。像这样的东西:

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 paramto it. Something like this:

由于您已经编写了大量与参数验证相关的代码,这使得函数变得繁琐且难以阅读。因此,您决定将此验证代码移动到函数 say, IsValidParam(),然后DoWork()通过将参数传递param给它来调用该函数。像这样的东西:

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 onlyby your other functions like DoWork(), then making IsValidParam()publicdoesn't make sense. So you decided to make this function private.

好的,你已经IsValidParam()在课堂上的某个地方写过,但你现在面临的问题是,你会制作这个函数public吗?如果此功能由您的其他功能使用,例如DoWork(),则IsValidParam()公开没有意义。所以你决定做这个功能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.

这种类型的函数 (IsValidParam) 应该是private. 我称这些函数为辅助函数

Hope this explanation helps you!

希望这个解释对你有帮助!

回答by Jonathan Wood

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.

OOP 的创始原则之一是封装。这是对象如何工作的功能保持在该对象内部的地方。这个想法是,如果代码不需要知道它是如何工作的,那么使用对象会更容易。有点像购买微波炉——你只需要知道如何使用它而不是它是如何工作的。

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.

对 OOP 也应采用相同的方法。保留维护对象私有所需的一切。仅公开充分使用对象所需的内容。

回答by Tony Delroy

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

如果你在设计一个类-考虑到这样的客户端代码应该使用它-那么你将不可避免地派生的接口包括public,也许protected成员。

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

private成员是支持和启用这些公共/受保护成员的功能和数据。 private函数应该对非private成员所需的代码进行分解和/或模块化/结构化,使它们的实现减少冗余并更容易理解。

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

总而言之,private如果它不打算由客户端代码直接使用,您就创建了一个成员,并且只存在以支持非private成员。

回答by Yttrill

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 wholeof 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.

私有辅助函数也可以放在 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 onlypermitted 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 holdprior to calling a public method and are required to holdafter 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.

在实践中,通常不会遵循这些规则,因为它们通常会生成琐碎的包装器,并且需要编写和维护大量额外的代码。所以虚函数通常最终是公开的,即使这在原则上是完全错误的。

回答by Justinonday

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 .

例如:“ConnectionString()”。每个数据库连接都需要“ConnectionString()”,因此它声明为 Public 。

回答by wqking

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.

private:只供本类使用,不供其他类或派生类使用。
protected:被这个类和派生类使用,但不被其他类使用。
public:由其他类、本类和派生类使用。

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.

很难在私有和受保护之间做出选择。因此,如果派生类可能需要它的可能性为 1%,我总是使函数受保护。