在处理类时为什么要使用get和set函数

C++ Why should I use get and set functions when working with classes

本文关键字:get set 函数 处理 为什么      更新时间:2023-10-16

我被告知不要在类中公开变量。我应该总是写get和set函数。例如:

class Whatever
{
public:
  void setSentence(const std::string &str) { sentence = str; }
  void setAnInteger(const int integer) { anInteger = integer; }
  std::string getSentence() { return sentence; }
  int getAnInteger() { return anInteger; }
private:
  std::string sentence;
  int anInteger;
};

我为什么要那样做?仅仅使用这些变量不是更方便吗?另外,这是一种好的c++编程风格吗?

主要是为了增加封装。如果你的类公开了这些成员变量,那么你的客户端代码中的许多函数将依赖于这些变量。

假设有一天你想要更改这些变量的名称,或者你想要更改类的实现,使成员变量的类型和数量与当前的不同:有多少函数会受到这种更改的影响?有多少函数需要重写(至少部分重写)?

对,可能是无限的。你不能把它们都数出来。另一方面,如果你有getter和setter,只有这4个函数可以访问你的类的内部表示。更改内部表示不需要更改客户端函数的代码;只有这4个成员函数可以被修改。

一般来说,封装使将来的更改更容易。在某个时间点,您可能希望在每次设置某个属性时记录一条消息。您可能希望在每次设置某个属性时触发一个事件。您可能希望动态地计算某个值,而不是每次从缓存数据成员中读取它,或者从数据库中读取它,或者其他。

有了getter和setter,你就可以在不改变客户端代码的情况下实现这些改变。

就一般设计理念而言,在实现访问器与不实现整个社区都同意的访问器时,没有"总是"或"永远"之分。

许多人会建议您将所有数据成员设置为private,并提供访问器&调整器。总是这样。

如果不希望从客户端代码更改数据成员,则将其设置为private,否则将其保留为public

然而,其他人会告诉您,类不应该有多个数据成员,所有的数据都应该封装在另一个对象中,最好是struct

你必须自己决定哪一个是正确的,记住这不仅取决于你的方法,还取决于你所工作的组织的方法。

如果你问我,我的偏好是让所有的public,直到我有理由不这样做。简单。但那只是我的想法。

您编写显式getter和setter作为未来开发的合理计划。如果您的类的用户直接访问它的成员,并且您需要以一种与这种习惯不兼容的方式更改类,那么您必须更改以这种方式与您交互的每个代码块。如果您编写了getter和setter,编译器将对其进行优化,使其与直接访问的时间相当(如果这就是它所做的全部工作),并且您可以稍后根据需要更改逻辑,而无需更改大量其他代码。

当您创建get或set方法并在代码中使用它40次时,您可以更轻松地处理将来的更改。想象一下,你使用公共变量,并在你的代码中使用它40次。经过一个月的程序开发,您可能会想到一个好主意:如果我将这个变量除以1000,这样我就有更好的计算值了!哇,太棒了,但是现在我必须找到每一行,我使用它的地方并修改它。如果我只有一个get方法:(

)

这就是使用getter和setter的主要原因,即使它们非常简单,最好还是有。你会感谢自己一次。

数据封装是OOP的主要原则之一。它是将数据和函数组合成一个称为类的单元的过程。使用封装的方法,程序员不能直接访问数据。数据只能通过类中存在的函数来访问,因此对用户隐藏了类的实现细节。这是为了防止调用者和函数意外地改变方法的行为,或者不需要知道方法是如何工作的。

我在上第一个OOP课程时回忆起的教科书式答案是:Get和set方法用于封装私有变量。通常人们会比较get和set或者只是简单地将这些变量设置为公共;在这种情况下,get和set方法是很好的,因为它可以保护这些变量不因错误等而被意外修改。

人们(当我上这门课的时候)可能会问"get和set是不是也修改这些变量,如果是这样,那和作为公共变量修改有什么不同?"

的基本原理是:有get和set函数,你要求用户或你自己明确指定他们想要通过调用这些函数来修改变量。在不调用这些函数的情况下,私有变量不太可能被不情愿地或意外地修改(仍然有可能取决于实现)。

总之,您不应该这样做。

一般来说,我建议阅读Fowler的重构,然后你会有一个画面,有裸露的数据会阻碍什么,什么样的访问对齐好。更重要的是,整件事是否适用于你的案例。

正如你所知道的,你可以安全地忽略"应该做/不应该做"之类的东西,比如在这个答案的开头或其他地方。