这有什么奇怪的魔力?

时间:2012-10-25 06:24:47

标签: c++

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

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

(N的类型是结构)

N N::someMethod() const {

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

}

它会返回原始结构的修改副本,并且原始结构未经修改。

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

我的理解是'这'是一个指针。我曾经想过,当你*一个指针时,它只是取消引用那个指针? (所以我希望n指向与原版相同的内存块,但显然它没有,所以我的直觉是borken)

如果您愿意,请随时指出我的方式错误。没关系,我很聪明,能够详细讨论引擎盖下发生的事情,我保证!

6 个答案:

答案 0 :(得分: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.

答案 1 :(得分:6)

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

答案 2 :(得分:3)

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

其余为dereference operator*,类似于

N n1;
N n2 = n1; // initialize n2 copying the value of n1

答案 3 :(得分:3)

N n = *this;

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

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

答案 4 :(得分: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 )

答案 5 :(得分:1)

你说“这个”是指针是正确的。 “这个”是指向你所在对象实例的指针,如果这是有道理的。

我认为问题是“N n = * this”这一行。

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

我相信你所寻找的东西更像是这样:

N * N::someMethod() {

    this->modify();
    return this;
}

- &gt;运算符与写“(* this)。”相同。

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

此外,除非修改也是一个const方法(看起来名字不太可能),你不应该将someMethod写为const方法。 (您不能在const方法中更改对象的逻辑内容。)