为什么“this”是指针而不是引用?

Why is 'this' a pointer and not a reference?

提问人:Naveen 提问时间:3/14/2009 最后编辑:CommunityNaveen 更新时间:11/21/2021 访问量:36356

问:

我正在阅读这个问题的答案 C++ 的优缺点,并在阅读评论时产生了这个疑问。

程序员经常发现“this”是一个指针而不是引用,这令人困惑。另一个混淆是为什么“hello”不是 std::string 类型,而是计算结果为 char const* (指针) (在数组到指针转换之后) – Johannes Schaub - litb Dec 22 '08 at 1:56

这仅表明它没有使用与其他(后来的)语言相同的约定。– le dorfier Dec 22 '08 at 3:35

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

这是一个恒定的 poiner 吗?– yesraaj Dec 22 '08 at 6:35

如果方法是 const int getFoo() const,这可以是常量;<- 在 getFoo 的范围内,“this”是常量,因此是只读的。这样可以防止 bug,并为调用方提供一定程度的保证,即对象不会更改。– Doug T. Dec 22 '08 at 16:42

您无法重新分配“this”。也就是说,你不能做“this = &other;”,因为这是一个右值。但这属于 T* 类型,而不是 T const 类型。即它是一个非常量指针。如果你使用的是 const 方法,那么它是指向 const 的指针。但指针本身是非常量的 – Johannes Schaub - litb Dec 22 '08 at 17:53

可以这样考虑“this”:#define this (this_ + 0),编译器创建“this_”作为指向对象的指针,并使“this”成为关键字。不能分配“this”,因为 (this_ + 0) 是右值。当然不是这样(没有这样的宏),但它可以帮助理解它 – Johannes Schaub - litb Dec 22 '08 at 17:55

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


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

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

评论

6赞 iFreilicht 6/16/2014
@paulm 这个“黑客”实际上会完成什么?并不总是评估到?thistrue
6赞 antred 8/26/2014
@paulm我认为这实际上C++无效。对对象调用 nullptr 上的方法会导致未定义的行为。
5赞 Jason C 5/9/2015
@paulm 也许它在某些情况下有效,但想象一下,如果这种方法是有毒的。如何在没有对象的情况下进行 V 表查找?
4赞 Alice 9/13/2015
@paulm 如果你在生产代码中看到过它,那就弃船吧!那就是UB。
8赞 Christopher Oicles 10/20/2015
我只是要把这个留在这里......(来自 MFC 的 afxwin2.inl):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }

答:

198赞 Daniel Earwicker 3/14/2009 #1

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

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

评论

5赞 jalf 3/14/2009
好吧,对于对象来说,获取对自身的引用通常也很有用。我会说这是一个更常见的用法。无论如何,主要原因是就像你说的,当他们创建“this”指针时,引用并不存在。
25赞 Omnifarious 1/30/2010
而且,如果这是一个参考,那么很难超载去做任何有用的事情。必须有一些特殊的语法来获取这个不会通过的地址。operator &operator &
11赞 Daniel Earwicker 4/6/2010
@conio - 下次靠近 C++ 编译器时,您可能想检查一下!:)像这样:int n = 5; int &r = n; int *p = &r; std::cout << *p;
15赞 Johannes Schaub - litb 7/2/2010
@Omnifarious你可以写来获取重载的真实地址(事实上,这就是这样做的)。&reinterpret_cast<char&>(this);operator&boost::addressof
12赞 Ponkadoodle 2/2/2012
由于 null 没有任何意义,因此在我看来,引用确实更合适。this
130赞 Michael Burr 3/16/2009 #2

派对有点晚了......直接从马的嘴里,这是Bjarne Stroustrup要说的话(基本上在“C++的设计与进化”一书中重复或摘自):

为什么“”不是引用?this

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

评论

2赞 pilkch 6/18/2017
是的,self 会很好与其他语言保持一致,哦,好吧。
7赞 jxh 2/17/2021
self可能是一个像 .*this
6赞 David Callanan 6/10/2022
#define self *this
1赞 John Källén 5/19/2023
#define self (*this)
10赞 oficsu 11/21/2021 #3

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

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

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

评论

1赞 tmlen 8/30/2023
任何可以写类似东西的语言都有一些固有的问题......似乎随着所有新的 C++ 修订版,他们添加了越来越多的东西,这些东西只是修复语言本身的问题,而不是添加功能。、、等this Self&& selfforward_likedeclvalto_addresslaunderstart_lifetime_asenable_ifvoid_tdestroying_delete_treference_wrappermove_only_functionbind_front/back
0赞 ColinBroderick 11/28/2023
这些东西增加了在真正重要的时候对应用程序进行更细粒度的控制,以及更安全/更简单的方法来完成任务,否则会很痛苦。C++首先是一种系统语言。完全控制一切是绝对要求。所以自然会有很多肮脏的接口,因为系统是肮脏的地方。