5

快速提问。我想了解 *this 在 C++ 中的行为。如果这太明显或重复,请原谅我,因为搜索引擎将 * 解释为通配符,我的搜索有点不够启发性。

我正在使用别人的代码,它有许多看起来像这样的函数:

(N 的类型是结构)

N N::someMethod() const {

    N n = *this;
    // do a function that modifies internal values of the struct
    n.modify();
    return n;

}

发生的情况是它返回原始结构的修改副本,而原始结构未修改。

我假设不知何故*这是在制作副本,但我不明白为什么/如何。这与结构有关吗?它是函数声明中的 const 吗?幕后是否还有其他的魔法?

我的理解是'this'是一个指针。我以为当你 * 一个指针时,它只是取消引用该指针?(所以我希望 n 指向与原始内存相同的内存块,但显然它没有,所以我的直觉很糟糕)

如果您愿意,请随时指出我的方式的错误。没关系,我很聪明,可以深入了解引擎盖下发生的事情的详细技术讨论,我保证!

4

6 回答 6

13

不,这是时间黎明前的魔法一个隐约可见的纳尼亚参考)。它让人联想到 C 语言。

既然this只是一个指向当前对象的指针,*this就是对象本身,而这一行:

N n = *this;

简单地复制所述对象。然后,它修改该副本并将其返回。

如果你想要一个指向同一个对象的指针的副本,那就是:

N *n = this;

这与以下没有什么不同:

int xyzzy = 7;           // xyzzy holds 7.
int *pXyzzy = &xyzzy;    // the address of xyzzy.

int plugh = *pXyzzy;     // a *different* address, also holding 7.
int *pTwisty = pXyzzy;   // copy *address*, pXyzzy/pTwisty both point to xyzzy.
于 2012-10-25T06:27:05.817 回答
6

*this它本身不会进行任何复制,它只会使类型正确,用于将由 . 调用的复制构造函数N n = ...

于 2012-10-25T06:27:45.663 回答
3

的类型this是“指向 N 的指针”,因此*this,应用于的取消引用运算符*thisN。表达式中没有执行复制*this。它只是提供对指向的对象的引用this

剩下的就是拷贝初始化,类似于

N n1;
N n2 = n1; // initialize n2 copying the value of n1
于 2012-10-25T06:27:10.740 回答
3
N n = *this;

称为复制初始化。它通常会创建一个副本。

它通过尝试转换*this为 type 的对象来构造一个隐式转换序列N,然后可以将该对象复制到 to-initialized 对象中,从而导致对复制构造函数的调用。

于 2012-10-25T06:27:23.573 回答
1

即使符号=存在,工作也由复制构造函数完成。

以下代码显示了其执行的一些回声:

#include <iostream>

class N {
public:

   N(){}

   N( const N & n ) {
      std::cout << "N( const N & n )" << std::endl;
   }

   N& operator = ( const N & n ) {
      std::cout << "N& operator = ( const N & n )" << std::endl;
      return *this;
   }

   N modify() const {
      std::cout << "modify|entry" << std::endl;
      N n2 = *this;
      std::cout << "modify|exit" << std::endl;
      return n2;
   }
};

int main() {
   N n1;
   n1.modify();
}

有了这个输出:

modify|entry
N( const N & n )
modify|exit
N( const N & n )
于 2012-10-25T06:27:12.823 回答
1

你是正确的,“this”是一个指针。如果有意义的话,“This”是指向您所在对象的实例的指针。

我相信问题出在“N n = *this”这一行。

您取消引用了指针并调用了复制构造函数。这是创建副本的行。

我相信您正在寻找的是更多类似以下内容的内容:

N * N::someMethod() {

    this->modify();
    return this;
}

-> 运算符与写“(*this)”相同。

请注意,我将方法更改为返回指针,或者当您将此函数的返回值分配给其他对象时,您可能最终会再次调用复制构造函数。

此外,除非 modify 也是一个 const 方法(根据名称,这似乎不太可能),否则您不应该将 someMethod 编写为 const 方法。(您不能在 const 方法中更改对象的逻辑内容。)

于 2012-10-25T06:32:49.450 回答