【问题标题】:Are public variables faster than using getters and setters?公共变量是否比使用 getter 和 setter 更快?
【发布时间】:2017-05-26 12:59:46
【问题描述】:

我正在为我正在制作的游戏编写自定义物理引擎,我的物理对象类有大量变量(距离、速度、加速度、质量、重力、力、脉冲持续时间等......)。为每个变量创建一个 setter 和 getter 函数会影响性能吗? (在给定时间将至少有 100 个此类的实例)

我还应该创建setter 和getter 吗?听说公共变量是个很不好的做法,但是有很多变量,这可以是一个例外吗?

【问题讨论】:

  • “我听说公共变量是非常糟糕的做法”你从哪里听说的?
  • C++ 中没有专门的 getter 和 setter,只有普通的成员函数。
  • 试试看。措施。基准。想想你的设计!虽然不存在性能影响,但公共成员变量或公共 getter/setter 函数之间真的有区别吗?基本的 OO 原则对封装有什么看法?如果你有getter/setter函数,成员变量真的被封装了吗?
  • 当您希望封装实现时,请使用 getter 和 setter。例如,可能由变量或其他值的计算提供的值。
  • 答案是:视情况而定。假设您有一个带有 Point getPoint() 的 Shape 实例,它实际上会从不同的内部值创建一个 Point 实例。这是一个很好的吸气剂示例。但是您真的需要 int Point::getX() 的吸气剂还是我们可以直接调用 myShape.getPoint().x 吗?

标签: c++ performance optimization


【解决方案1】:

为每个变量创建一个 setter 和 getter 函数会影响性能吗? (在给定时间将至少有 100 个此类的实例)

可能没有。理论上是的,但在实践中,调用额外函数来获取特定值的成本可以忽略不计。它会影响性能的唯一方法是,如果您最终一直调用这些方法(例如...每秒 50000 次)。

我还应该创建 setter 和 getter 吗?

可能没有。良好的 OO 设计遵循称为“告诉,不要问”的准则。通常,您应该查看需要这些变量进行哪些操作,然后在类中实现这些操作,或者在具有访问权限的类中实现它们,或者使用不同的模型(想到访问者模式)。

我听说公共变量确实不好,但是有很多变量,这可以是一个例外吗?

拥有公共变量并不是一个坏习惯。当你有不变量时有公共变量是不好的做法。

例如,如果您有一个测量对象重量的变量,您需要确保不能将其设置为无效值(例如负数或大得离谱的量)。如果您将变量公开,您将不得不检查您在客户端代码中修改它的任何地方设置的值,或者放弃验证该值。

两者都很糟糕,因为如果你有一个带有验证的propper setter,它们是不可能存在的错误。

简而言之,只有在没有不变量的情况下才可以使用公共变量。

注意事项:

  • 使用公共变量,如果设置变量类型允许的任何值都可以,在任何时候(你没有不变量)

  • 如果有不变量,请使用私有变量。

  • 使用公共方法来定义操作,而不是“访问内部变量”。

  • 根据您从客户端代码查看时要执行的操作来设计您的公共 API,而不是根据 内部实现中存在的变量 em>.

在这种情况下,getter 和 setter 有时(很少)有意义,但不是因为您在类中有变量。

  • getter 和 setter 是试图在错误的地方解决问题的症状:如果您在 A 类中有一个使用 B 类变量的操作 X,那么您可能应该在 B 类中定义操作 X,然后调用它来自 A 班。

【讨论】:

  • 考虑非常好,为我的类中的变量设置任何值都不会破坏任何东西,我将使用公共变量。
  • “在实践中,调用额外函数来获取特定值的成本可以忽略不计”——尤其是如果优化器正确地删除了函数抽象(内联);在这种情况下,它将为零。
【解决方案2】:

为每个变量创建一个 setter 和 getter 函数会影响性能吗?

对于简单的 getter/setter 函数,它们通常可以由编译器内联,因此不会影响性能。

我还应该创建setter 和getter 吗?我听说公共变量是非常糟糕的做法

公共变量本身并不是一个坏习惯,但通常您希望将数据封装在一个类中,尤其是在对其应用计算时。

只提供 getter/setter 函数的类是无用的,这些通常可以简单地替换为带有所有公共变量的 struct

【讨论】:

  • 我只是在输入一个具有相同想法的答案。 :] 有时我很惊讶你们的速度有多快。
  • 仅提供 getter/setter 函数的类在调试时会有些用处:您可以在访问器函数上设置断点,以帮助追踪值的神秘变化来自何处。
  • 只提供访问器方法的类可以演变成更多的类,而不会破坏过程中的任何东西。简单的结构不能。
  • @PeteBecker 如果您需要,您的系统设计可能还有其他问题。
  • @VishnuShankar 如果您的值正在被其他类修改,则它们未封装。将数据成员包装在 getter/setter 中不会改变这一点
【解决方案3】:

只是公共变量违反了OO设计原则,而getter setter却没有,这就是为什么我们需要用户总是getter和setter

【讨论】:

    最近更新 更多