繁体   English   中英

为什么我们在赋值运算符中返回 *this 并且通常(而不是 &this)当我们想要返回对 object 的引用时?

[英]Why do we return *this in asignment operator and generally (and not &this) when we want to return a reference to the object?

我正在学习 C++ 和指针,在看到这个之前我以为我理解了指针。

一方面,asterix(*) 运算符正在取消引用,这意味着它返回值指向的地址中的值,而与符号 (&) 运算符则相反,并返回值存储位置的地址memory。

现在阅读有关赋值重载的内容,它说“我们返回*this因为我们想返回对该对象的引用”。 尽管从我读到的*this实际上返回了 this 的值,并且如果我们想返回对 object 的引用,那么逻辑上应该返回&this

这怎么加起来? 我想我在这里遗漏了一些东西,因为我没有在其他地方找到这个问题,但解释似乎与应该是什么完全相反,关于 * 取消引用的逻辑,并获得参考。

例如这里:

struct A {
  A& operator=(const A&) {
    cout << "A::operator=(const A&)" << endl;
    return *this;
  }
};

this是一个保持当前 object 地址的指针。因此像*this这样取消引用指针你将获得当前 object 本身的左值。 并且呈现的 class 的复制赋值运算符的返回类型是A& 所以返回表达式*this就是返回对当前 object 的引用。

根据C++ 17标准(8.1.2本)

1关键字 this 命名指向 object 的指针,为此调用非静态成员 function (12.2.2.1) 或评估非静态数据成员的初始值设定项 (12.2)。

将以下代码片段视为一个简化示例。

int x = 10;

int *this_x = &x;

现在要返回对 object 的引用,您需要使用表达式*this_x作为示例

std::cout << *this_x << '\n';

&根据上下文有多种含义。 在 C 中单独使用时,I 可以是按位与运算符,也可以是符号引用的地址。

在C++中,在一个类型名之后,也意味着后面是对这个类型的一个object的引用

这意味着您输入:

int     a = 0;
int &   b = a;

b将成为a事实上的别名。

在您的示例中, operator=返回类型为 A 的 object (不是指向它的指针)。 这将被 uppers 函数以这种方式看到,但实际返回的是一个现有的 object,更具体地说是调用了该成员 function 的 class 的实例。

是的, *this是(的值?)当前 object。但是指向当前 object 的指针是this ,而不是&this

&this如果它是合法的,将是一个指向当前 object 的指针。但它是非法的,因为this (指针本身)是一个临时的 object,你不能使用&获取那些地址。

问为什么我们不return this; .

答案是:形成一个指针需要& ,但形成一个引用则不需要。 相比:

int x = 42;
int *ptr = &x;
int &ref =  x;

所以,类似地:

int *f1() return {return &x;}
int &f1() return {return  x;}

您可以使用的一个简单助记符是*&运算符匹配您要转换的对象的类型语法,而不是您要转换的对象的类型语法:

  • *foo*转换为foo&
  • &foo&转换为foo*

在表达式中, foofoo&之间没有有意义的区别,所以我可以说*foo*转换为foo ,但上面的版本更容易记住。

C++ 继承了 C 的类型语法,C 类型语法以使用它们的表达式语法命名类型,而不是创建它们的语法。 Arrays 被写为foo x[...]是因为您通过访问元素来使用它们,而指针被写为foo *x是因为您通过取消引用它们来使用它们。 指向 arrays 的指针被写为foo (*x)[...]因为您通过取消引用它们然后访问元素来使用它们,而 arrays 的指针被写为foo *x[...]因为您通过访问元素来使用它们然后取消引用它。 人们不喜欢语法,但它是一致的。

引用是后来添加的,破坏了一致性,因为使用引用的语法与“直接”使用引用的 object 没有任何不同。 因此,您不应该试图理解引用的类型语法。 就是这样。

this是一个指针的原因也纯粹是历史原因: this是在引用之前添加到 C++ 的。 但是因为它是一个指针,而你需要一个引用,你必须使用*来摆脱*

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM