什么是'this'指针?

18

我对C++还比较陌生,不太理解在以下情况下this指针的作用:

void do_something_to_a_foo(Foo *foo_instance);


void Foo::DoSomething()
{
  do_something_to_a_foo(this);
}

我从别人在这里发布的帖子中获取了这个。

this指向什么?我很困惑。该函数没有输入,那么this是做什么的?


所有非静态方法都有一个隐式的 this 指针。在典型的 C++ 实现中,它会传递到第一个整数参数槽中。 - Matthew Lundberg
我会避免做这样的事情 - 任何“对foo进行操作”的函数都应该是Foo的成员函数/方法! - Wayne Uroda
@Wayne Uroda:完全不一定。 - Alexander Shukaev
@WayneUroda,“probably”可能有点过于强烈。 - Nik Bougalis
“可能是Foo方法的一个很好的候选方法”这个说法怎么样?能否给我举个反例? :) - Wayne Uroda
显示剩余2条评论
8个回答

34

this 指的是当前对象。

this 关键字表示一种特殊类型的指针。假设你创建了一个名为 x 的对象,它是 class A 的一个实例,并且 class A 包含一个非静态成员函数 f()。如果你调用函数 x.f(),那么在 f() 函数体中,关键字 this 存储着 x 的地址。


9
简短的回答是this是一个特殊的关键字,用于标识“这个”对象——你当前正在操作的对象。稍微长一点、更复杂的答案是这样的:
当你有一个class时,它可以有两种类型的成员函数:static和非static。非static成员函数必须在类的特定实例上操作,并且它们需要知道该实例在哪里。为了帮助它们,语言定义了一个隐含变量(即当需要时会自动为您声明的变量),称为this,它将自动指向成员函数所操作的类的特定实例。
考虑这个简单的例子:
#include <iostream>

class A
{
public:
    A() 
    { 
        std::cout << "A::A: constructed at " << this << std::endl;
    } 

    void SayHello()
    {
        std::cout << "Hi! I am the instance of A at " << this << std::endl;
    }
};

int main(int, char **)
{
    A a1;
    A a2;

    a1.SayHello();        
    a2.SayHello();

    return 0;
}

当您编译并运行此代码时,请注意a1a2之间this的值不同。

3

这里是关于this的一些随机事实,补充其他答案:

class Foo {
public:
    Foo * foo () { return this; }
    const Foo * cfoo () const { return this; /* return foo(); is an error */ }
};

Foo x;       // can call either x.foo() or x.cfoo()
const Foo y; // can only call x.cfoo()

当对象是const时,this的类型变成了指向const的指针。


class Bar {
    int x;
    int y;
public:
    Bar () : x(1), y(2) {}
    void bar (int x = 3) {
        int y = 4;
        std::cout << "x: " << x << std::endl;
        std::cout << "this->x: " << this->x << std::endl;
        std::cout << "y: " << y << std::endl;
        std::cout << "this->y: " << this->y << std::endl;
    }
};

this指针可以用于访问被函数参数或局部变量所遮蔽的成员。


template <unsigned V>
class Foo {
    unsigned v;
public:
    Foo () : v(V) { std::cout << "<" << v << ">" << " this: " << this << std::endl; }
};

class Bar : public Foo<1>, public Foo<2>, public Foo<3> {
public:
    Bar () { std::cout << "Bar this: " << this << std::endl; }
};

多重继承会导致不同的父类有不同的this值。只有第一个被继承的父类将与派生对象具有相同的this值。


2
这意味着在调用DoSomething()的Foo对象上。我将用一个例子来解释它。
void do_something_to_a_foo(Foo *foo_instance){
    foo_instance->printFoo();
}

我们的类
class Foo{
    string fooName;
    public:
        Foo(string fName);
        void printFoo();
        void DoSomething();
};

Foo::Foo(string fName){
     fooName = fName;
}
void Foo::printFoo(){
      cout<<"the fooName is: "<<fooName<<endl;
}
void Foo::DoSomething(){
     do_something_to_a_foo(this);
}

现在我们像这样实例化对象:

Foo fooObject("first);
f.DoSomething();//it will prints out first

同样地,无论传递给Foo构造函数的字符串是什么,在调用DoSomething()时都将被打印出来。
因为例如在上面示例中的DoSomething()中,“this”表示fooObject,在do_something_to_a_foo()中,fooObject是按引用传递的。


2

this是指向自身的指针(调用this的对象)。

假设您有一个名为car的Car类对象,其中包含一个非静态方法getColor(),在getColor()中调用this将返回car的地址(该类的实例)。

静态成员函数没有this指针(因为它们与实例无关)。


2

根据Balaguruswamy的《面向对象编程与c++》

this是一个指针,它指向调用this函数的对象。例如,函数调用A.max()将把指针this设置为该对象的地址。指针this作为所有成员函数的隐式参数。

您可以在这里找到一个很好的this指针示例。它也帮助我理解了这个概念。 http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/


1
非静态成员函数例如 Foo::DoSomething 具有一个隐式参数,其值用于 this。C++11 §5.2.2/4规范了这一点:

当调用函数时,每个参数 (8.3.5) 都应该使用其相应的参数进行初始化 (8.5, 12.8, 12.1)。[注:这样的初始化与彼此的顺序是不确定的 (1.9) — 结束注释] 如果函数是一个非静态成员函数,则函数的 this 参数 (9.3.2) 应该被初始化为指向调用对象的指针,转换方式就像通过显式类型转换一样 (5.4)。

因此,您需要一个 Foo 对象来调用 DoSomething。该对象直接成为 thisthis 关键字和常规的明确声明的 const 指针参数之间唯一的区别(它微不足道)是您无法获取 this 的地址。

0

这是一个本地指针。它将当前对象作为本地对象引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接