【问题标题】:What is the advantage of having this/self pointer mandatory explicit?强制显式 this/self 指针有什么好处?
【发布时间】:2010-10-28 22:38:30
【问题描述】:

this/self/me 指针强制显式有什么好处?

根据OOP 理论,方法应该主要(仅?)对成员变量和方法的参数进行操作。在此之后,引用成员变量应该比引用外部(从对象的角度)变量更容易...显式 this 使其更冗长,因此 更难 引用成员变量而不是外部变量。这对我来说似乎违反直觉。

【问题讨论】:

    标签: language-agnostic oop programming-languages language-theory


    【解决方案1】:

    除了成员变量和方法参数之外,您还有局部变量。关于对象的最重要的事情之一是它的内部状态。显式成员变量取消引用使您在何处引用该状态以及您在何处修改该状态非常清楚。

    例如,如果您有如下代码:

    someMethod(some, parameters) {
        ... a segment of code
        foo = 42;
        ... another segment of code
    }
    

    当快速浏览它时,您必须对前一段中定义的变量有一个心智模型,以了解它是否只是一个临时变量或它是否会改变对象状态。而 this.foo = 42 则很明显对象状态已发生变化。如果专门使用显式取消引用,则可以确保该变量在相反的情况下是临时的。

    更短、设计合理的方法使其不那么重要,但在编写代码时,长期的可理解性仍然胜过一点便利。

    【讨论】:

    • 在出现范围问题时很有用(本地范围的 foo 将隐藏类成员变量 foo),但考虑到其他地方的 OP 的 cmets,它不是严格强制的,只是方便。
    • 我还需要一个“心智模型”来知道我是在if 还是while 内;为什么我们不在所有这些命令的前面加上该信息?
    • @RobertPaulson:这个问题可以通过要求从某些外部范围显式隐藏变量来解决。
    • 这非常有用。但它应该是可选的。我是从关于强制性“自我”的讨论中来到这里的。 Python 的作用域修饰符。过度使用此类修饰符(如在 Python 中所见)会乱扔代码并降低整体可读性。
    【解决方案2】:

    如果您谈论的是 Python 意义上的“显式self”,这里有一个关于该主题的interesting discussion。这是Guido respondingBruce Eckel's article。 Bruce 文章中的 cmets 也很有启发性(其中一些,无论如何)。

    【讨论】:

      【解决方案3】:

      您需要将指针/引用传递给其他地方的当前对象或防止在赋值运算符中进行自赋值。

      【讨论】:

      • 我添加了“强制”这个词,因为这就是我要问的。
      【解决方案4】:

      如果方法的参数与成员变量同名怎么办?例如,您可以使用this.x = x。其中this.x 是成员变量,x 是方法参数。 这只是一个(微不足道的)示例。

      【讨论】:

      • 我添加了“强制”这个词,因为这就是我要问的。
      【解决方案5】:

      我通常仅在编写 赋值运算符复制构造函数 时使用它(在 C++ 中),因为它有助于清楚地识别变量。我可以考虑使用它的其他地方是,如果您的函数参数变量名称与您的成员变量名称相同,或者我想使用 delete this 杀死我的对象。

      【讨论】:

      • 是我自己还是打电话delete this 好像真的不对?
      • 一般来说这是个坏主意..但在某些情况下你可能想做一个引用计数对象。
      • 如果您希望“递减计数器,检查值并在需要时删除”的操作成为单一方法,那么在引用计数对象的情况下,您别无选择。
      • 引用计数的对象不应该删除自己,它应该删除它引用的对象。
      【解决方案6】:

      例如,成员名称与传递给方法的名称相同

      public void SetScreenTemplate(long screenTemplateID, string screenTemplateName, bool isDefault)
              {
                  this.screenTemplateID = screenTemplateID;
                  this.screenTemplateName = screenTemplateName;
                  this.isDefault = isDefault;
              }
      

      【讨论】:

        猜你喜欢
        • 2021-12-23
        • 2013-04-16
        • 1970-01-01
        • 2013-05-05
        • 2012-05-22
        • 2017-08-26
        • 2016-08-15
        • 2013-06-14
        • 1970-01-01
        相关资源
        最近更新 更多