【问题标题】:Copy reference operator returning a reference not an object using the keyword 'this'复制引用运算符使用关键字“this”返回引用而不是对象
【发布时间】:2020-12-02 13:47:06
【问题描述】:

我想问一个关于复制引用运算符的问题。

我有一个名为 Mystring 的类,并且我有一个复制引用运算符,它可以工作。

#ifndef _MY_STRING_
#define _MY_STRING_

class Mystring
{
private:
    char *str; // pointer to a char[] that holds a c-style string
public:
    Mystring(); // no args
    Mystring(const char *s); // overloaded
    Mystring(const Mystring &source); // copy
    ~Mystring(); // destructor

    Mystring &operator=(const Mystring &rhs);// overloaded copy assignment operator

    void display() const; // getters
    int get_length() const;
    const char *get_str() const; // pointer is returned

};

#endif // _MY_STRING_

这是复制引用运算符函数:

// Overloaded assignment copy operator
Mystring &Mystring::operator = (const Mystring &rhs) {
    std::cout << "Copy assignment" << std::endl;
    if (this == &rhs) // check the pointer is on the same address of rhs i.e. & = reference operator
        return *this; // returns the reference
    delete [] this->str;
    str = new char [std::strlen(rhs.str) + 1];
    std::strcpy(this->str, rhs.str);
    return *this;
}

我是 C++ 的初学者,所以这很令人困惑,但我会尝试描述会发生什么。

我知道有一个this 运算符,它充当指针。当取消引用时,它允许我们使用对象本身。

从第一行开始

Mystring &Mystring::operator = (const Mystring &rhs)

我可以看到我将有一个返回引用的运算符函数,因为 &amp; 运算符存在于声明中。

但是,在 if 语句和整个函数的末尾,我们声明

return *this

虽然如果我们取消引用 this,我们将返回对象而不是根据我上面的解释的引用。

Microsoft c++ 文档还指出

表达式*this通常用于从成员函数返回当前对象:

为了澄清,this 是一个指向当前对象的指针,所以*this 然后返回它应该意味着我正在返回对象,而不是另一个引用。

我在理解这段代码时犯了什么错误?

【问题讨论】:

  • #define _MY_STRING_ 该标识符保留给语言实现。通过定义它,您的程序将具有未定义的行为。您应该使用另一个标头保护。
  • *this 和所有命名变量都可以绑定到引用,因为它们是对其对象的左值(~命名)引用。 &amp; 也有多种含义——一个是变量的地址,另一个是引用类型,它们并不完全相同。所以int&amp; var*ptr 不是相反的操作。 int var; int*ptr =&amp;var*ptr 将是。
  • @Quimby 我理解,但我的困惑是return *this 暗示将返回对象本身,但是代码似乎通过声明将返回对当前对象的引用来工作,并且我不明白这是怎么回事。 this 是指向当前对象的指针,所以 *this 然后返回它应该意味着我正在返回对象,而不是另一个引用。我希望这能让我的原意更清楚。
  • @bodn19888 是的,它归结为表达式的value categories,这不是一个真正适合初学者的话题。但是*this 本身就是一个命名引用。这就是为什么您的字符串复制构造函数可以执行std::string str; Mystring s(str) 之类的操作。这里str 也必须参考。它必须,首先您将如何分配给引用。没有str 的副本,只是参考。这完全一样,但是对象的名称是*this,它也可以绑定到一个引用。
  • int var;, var 表示我是我存储的对象的名称。 int&amp; r = var 意味着 r 将只是同一对象的另一个名称。 int var2 = var 的意思是:我将复制var 所引用的对象,并将为这个新对象重新命名。 *this 也只是一个名字,不用担心this 是一个指针。您可以使用Mystring s = *this 并复制一份名为s 的副本。或者您可以执行 Mystring&amp; r = *this 并且会发生与 int&amp; 完全相同的事情,r 将引用与 *this 相同的对象,即为该对象指定一个新名称。

标签: c++ object reference


【解决方案1】:

在 C++ 中,有些表达式的求值只是确定对象的身份。它们被称为 glvalue 表达式。这是表达式*this 的情况。 this 保存一个表示内存中地址的值,而表达式 *this 的计算结果是该地址处对象的标识。将其称为评估可能很奇怪,这只是一个名称:*this 指定位于this 持有的地址的对象。

一个返回引用的函数,当调用时产生一个glvalue:它只是指定一个对象。在operator = 的情况下,此对象是由返回语句*this 中的表达式指定的对象。

【讨论】:

    【解决方案2】:

    为了澄清,this 是一个指向当前对象的指针,所以*this 然后返回它应该意味着我正在返回对象,而不是另一个引用。

    你是对的,this 是指针,*this 是指针指向的对象。

    不过,看看你如何处理引用。例如,考虑通过引用将值传递给函数。它是通过以下方式完成的:

    void foo(char &param) {
      // do something
    }
    
    int main(int argc, char **argv) {
    
        int x = 5;
        
        foo(x);
        
        return 0;
    }
    

    请注意,变量 x 是通过引用传递的,但不需要 &amp;* 向编译器表明这一点。这是因为编译器可以自己解决。这也是你返回*this的原因,理解为参考。

    【讨论】:

      猜你喜欢
      • 2019-02-13
      • 2020-06-19
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      相关资源
      最近更新 更多