【问题标题】:Why is 'this' a pointer and not a reference?为什么'this'是指针而不是引用?
【发布时间】:2010-10-13 08:36:17
【问题描述】:

我正在阅读这个问题的答案C++ pros and cons,并在阅读 cmets 时遇到了这个疑问。

程序员经常发现“this”是一个指针而不是一个引用令人困惑。另一个困惑是为什么“hello”不是 std::string 类型,而是计算为 char const*(指针)(在数组到指针转换之后) – Johannes Schaub - 2008 年 12 月 22 日 1:56

这仅表明它没有使用与其他(后来的)语言相同的约定。 – le dorfier 2008 年 12 月 22 日 3:35

不过,我认为“这个”是一个非常微不足道的问题。哎呀,感谢您在我的未定义行为示例中发现了一些错误。 :) 虽然我不明白关于大小的信息与第一个中的任何内容有什么关系。根本不允许指针指向分配的内存之外 – jalf 2008 年 12 月 22 日 4:18

这是一个常数指针吗? – yesraaj 2008 年 12 月 22 日在 6:35

如果方法是 const int getFoo() const; 则 this 可以是常量

您不能重新分配“this”。即你不能做“this = &other;”,因为这是一个右值。但这是 T* 类型,而不是 T const 类型。即它是一个非常量指针。如果你在一个 const 方法中,那么它是一个指向 const 的指针。常数。但指针本身是非常量的 – Johannes Schaub - 2008 年 12 月 22 日 17:53

这样想“this”:#define this (this_ + 0) 其中编译器创建“this_”作为指向对象的指针,并使“this”成为关键字。您不能分配“this”,因为 (this_ + 0) 是一个右值。当然不是这样(没有这样的宏),但它可以帮助理解它 – Johannes Schaub - 2008 年 12 月 22 日 17:55

我的问题是,为什么 this 是指针而不是引用?让它成为指针有什么特别的原因吗?


为什么this 作为参考是有意义的一些进一步的论点:

  • 考虑 Item 1More Effective C++ :在保证我们有一个有效对象即不是 NULL 时使用引用(我的解释)。
  • 此外,引用被认为比指针更安全(因为我们不能用杂散的指针搞砸内存)。
  • 第三,访问引用的语法 (.) 比访问指针 (->(*)) 更好更短。

【问题讨论】:

  • @paulm 这个“黑客”实际上会完成什么? this 不总是评估为 true 吗?
  • @paulm 我认为这实际上不是有效的 C++。对对象调用 nullptr 上的方法会导致未定义的行为。
  • @paulm 也许它在某些情况下有效,但想象一下该方法是否具有病毒性。如何在没有对象的情况下进行 v-table 查找?
  • @paulm 如果您在生产代码中看到它,请弃船!那是UB。
  • 我要把它留在这里...(来自 MFC 的 afxwin2.inl):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }

标签: c++ pointers reference this c++-faq


【解决方案1】:

当语言第一次发展时,在与真实用户的早期版本中,没有引用,只有指针。添加运算符重载时添加了引用,因为它需要引用一致地工作。

this 的用途之一是让对象获得指向自身的指针。如果是参考,我们必须写&this。另一方面,当我们编写赋值运算符时,我们必须使用return *this,它看起来更简单为return this。所以如果你有一张白纸,你可以用任何一种方式争论。但是 C++ 逐渐演变为响应来自用户社区的反馈(就像大多数成功的事情一样)。向后兼容性的价值完全压倒了 this 作为引用或指针所带来的次要优势/劣势。

【讨论】:

  • 嗯,对象获取对自身的引用通常也很有用。我会说这是一个更常见的用法。无论如何,主要原因就像您说的那样,在创建“this”指针时引用不存在。
  • 而且,如果这是一个参考,那么将很难重载 operator & 来做任何有用的事情。必须有一些特殊的语法来获取不会通过operator & 的地址。
  • @conio - 你可能想在下次靠近 C++ 编译器时检查一下! :) 类似:int n = 5; int &r = n; int *p = &r; std::cout << *p;
  • @Omnifarious 你可以写&reinterpret_cast<char&>(this); 来获取重载operator& 的真实地址(事实上,这就是boost::addressof 所做的)。
  • 因为this 为空并没有任何意义,所以在我看来引用确实更合适。
【解决方案2】:

派对有点晚了...直接从马嘴里说出来,here's what Bjarne Stroustrup has to say(基本上在“C++ 的设计和进化”一书中重复或摘自):

为什么“this”不是参考?

因为“this”在添加引用之前被引入 C++(实际上是带类的 C)。另外,我选择了“this”来遵循 Simula 的用法,而不是(后来)Smalltalk 对“self”的使用。

【讨论】:

  • 是的,self 会很好地与其他语言保持一致,哦,好吧。
  • self 可能是一个类似于*this 的关键字。
【解决方案3】:

除了其他答案之外,由于Deducing thisin C++23,因此可以引用对其调用成员函数的对象(而不是this 指针):

struct Foo {
  void bar(this Foo& self) {
    // self is a reference to Foo
  }
};

int main() {
  Foo foo;
  foo.bar();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-09
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    相关资源
    最近更新 更多