“这个”是怎么来的?指针碰巧指向不同的对象?

发布于 2024-11-01 13:46:55 字数 504 浏览 5 评论 0原文

假设我有一个类:

class test {
public:
   void print();
private:
   int x;
};

void test::print()  
{  
    cout<< this->x;  
}

并且我有这些变量定义:

test object1;
test object2;

当我调用 object1.print() this 恰好存储 object1 的地址并且所以我从 object1 打印出 x ,当我调用 object2.print() this 时,它恰好存储了object2 ,我得到 x打印了object2。这是怎么发生的?

Suppose I have a class:

class test {
public:
   void print();
private:
   int x;
};

void test::print()  
{  
    cout<< this->x;  
}

and I have these variable definitions:

test object1;
test object2;

When I call object1.print() this happens to store address of object1 and so I get x from object1 printed and when I call object2.print() this happens to store address of object2 and I get x from object2 printed. How does it happen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

陪你搞怪i 2024-11-08 13:46:55

每个非静态成员函数都有一个隐式隐藏的“当前对象”参数,该参数作为 this 指针向您公开。

因此,您可以认为

test::print();

有一些

test_print( test* this );

全局函数,因此当您

objectX.print();

在代码中编写时,编译器会插入一个调用

test_print(&objectX);

,这样成员函数就知道“当前”对象的地址。

Each non-static member function has an implicit hidden "current object" parameter that is exposed to you as this pointer.

So you can think that for

test::print();

there's some

test_print( test* this );

global function and so when you write

objectX.print();

in your code the compiler inserts a call to

test_print(&objectX);

and this way the member function knows the address of "the current" object.

尝蛊 2024-11-08 13:46:55

您可以将 this 指针视为函数的隐式参数。想象一个小类,

class C {
public:
  C( int x ) : m_x( x ) { }

  void increment( int value ) {
    m_x += value; // same as 'this->m_x += value'
  }

  int multiply( int times ) const {
    return m_x * times; // same as 'return this->m_x * times;'
  }

private:
  int m_x;
};

它允许您编写像

C two( 2 );
two.increment( 2 );
int result = two.multiply( 3 );

现在这样的代码,实际发生的是使用额外的指针参数调用成员函数 incrementmultiply ,指向调用该函数的对象。该指针在方法内称为 thisthis 指针的类型有所不同,具体取决于该方法是否为 const(如 multiply 所示)或不是(如增量)。

您也可以自己做类似的事情,请考虑:

class C {
public:
  C( int x ) : m_x( x ) { }

  void increment( C * const that, int value ) {
    that->m_x += value;
  }

  int multiply( C const * const that, int times ) const {
    return that->m_x * times;
  }

private:
  int m_x;
};

您可以编写如下代码

C two( 2 );
two.increment( &two, 2 );
int result = two.multiply( &two, 3 );

注意,对于 multiply,this 指针的类型是 C const * const 函数,所以指针本身是 const 而且是被指向的对象!这就是为什么您不能更改 const 方法内的成员变量 - this 指针的类型禁止这样做。这可以使用 mutable 关键字来解决(我不想偏离太远,所以我宁愿不解释它是如何工作的),甚至可以使用 const_cast:

int C::multiply( int times ) const {
  C * const that = const_cast<C * const>( this );
  that->m_x = 0; // evil! Can modify member variable because const'ness was casted away
  // ..
}

我之所以提到这一点,是因为它表明 this 并不像看起来那么特殊的指针,而且这种特殊的 hack 通常是比使成员变量 可变更好的解决方案 因为此 hack 是一个函数的本地函数,而 mutable 使变量对于该类的所有 const 方法都是可变的。

You can think of the this pointer being an implicit argument to the functions. Imagine a little class like

class C {
public:
  C( int x ) : m_x( x ) { }

  void increment( int value ) {
    m_x += value; // same as 'this->m_x += value'
  }

  int multiply( int times ) const {
    return m_x * times; // same as 'return this->m_x * times;'
  }

private:
  int m_x;
};

which allows you to write code like

C two( 2 );
two.increment( 2 );
int result = two.multiply( 3 );

Now, what's actually happening is that the member functions increment and multiply are called with an extra pointer argument, pointing to the object on which the function is invoked. This pointer is known as this inside the method. The type of the this pointer is different, depending on whether the method is const (as multiply is) or not (as is the case with increment).

You can do something like it yourself as well, consider:

class C {
public:
  C( int x ) : m_x( x ) { }

  void increment( C * const that, int value ) {
    that->m_x += value;
  }

  int multiply( C const * const that, int times ) const {
    return that->m_x * times;
  }

private:
  int m_x;
};

you could write code like

C two( 2 );
two.increment( &two, 2 );
int result = two.multiply( &two, 3 );

Notice that the type of the this pointer is C const * const for the multiply function, so both the pointer itself is const but also the object being pointed to! This is why you cannot change member variables inside a const method - the this pointer has a type which forbids it. This could be resolved using the mutable keyword (I don't want to get side-tracked too far, so I'll rather not explain how that works) but even using a const_cast:

int C::multiply( int times ) const {
  C * const that = const_cast<C * const>( this );
  that->m_x = 0; // evil! Can modify member variable because const'ness was casted away
  // ..
}

I'm mentioning this since it demonstrates that this isn't as special a pointer as it may seem, and this particular hack is often a better solution than making a member variable mutable since this hack is local to one function whereas mutable makes the variable mutable for all const methods of the class.

挽心 2024-11-08 13:46:55

思考这个问题的方法是,this 只是一个指向您当前正在使用的对象的内存的指针。因此,如果您执行 obj1.print(),则 this = &obj1;。如果执行 obj2.print(),则 this = &obj2;

The way to think about it is that this is simply a pointer to the memory for whichever object you're currently working with. So if you do obj1.print(), then this = &obj1;. If you do obj2.print(), then this = &obj2;.

梦巷 2024-11-08 13:46:55

this 对于不同的对象有不同的值

this has different values for different objects

柠栀 2024-11-08 13:46:55

类 test 的每个实例都有它自己的成员变量 x 的副本。由于 x 对于每个实例都是唯一的,因此该值可以是您想要的任何值。
变量 this 指的是与其关联的实例。您不必使用变量“this”。你可以这样写:

void test::print()
{
   cout << x;
}

Each instance of class test gets it's own copy of member variable x. Since x is unique for each instance, the value can be anything you want it to be.
The variable this, refers to the instance to which it is associated. You don't have to use the variable 'this'. You could just write:

void test::print()
{
   cout << x;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文