假设我有一个班级:
class test {
public:
void print();
private:
int x;
};
void test::print()
{
cout<< this->x;
}
我有这些变量定义:
test object1;
test object2;
当我致电object1.print()
时,this
恰好存储了object1
的地址,因此我从x
打印object1
,当我致电object2.print()
时} this
恰好存储了object2
的地址,我从x
打印了object2
。它是如何发生的?
答案 0 :(得分:6)
每个非静态成员函数都有一个隐式隐藏的“当前对象”参数,该参数作为this
指针向您公开。
所以你可以认为
test::print();
有一些
test_print( test* this );
全局函数,所以当你写
objectX.print();
在您的代码中,编译器会插入对
的调用test_print(&objectX);
这样成员函数就知道“当前”对象的地址。
答案 1 :(得分:2)
您可以认为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 );
现在,实际发生的是成员函数increment
和multiply
被一个额外的指针参数调用,指向调用该函数的对象。该指针在方法中称为this
。 this
指针的类型不同,具体取决于方法是const
(multiply
是否)(与increment
一样)。
你也可以自己做一些事情,考虑一下:
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 );
请注意,this
指针的C const * const
指针的类型为multiply
,因此指针本身都是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通常比制作成员变量mutable
更好。 hack是一个函数的本地函数,而mutable
使变量可以变为类的所有 const
方法。
答案 2 :(得分:1)
考虑它的方法是this
只是指向你当前正在使用的任何对象的内存的指针。因此,如果您执行obj1.print()
,那么this = &obj1;
。如果您执行obj2.print()
,则this = &obj2;
。
答案 3 :(得分:1)
this
具有不同对象的不同值
答案 4 :(得分:1)
每个类测试实例都获得它自己的成员变量x的副本。由于x对于每个实例都是唯一的,因此值可以是您想要的任何值。 变量this指的是与之关联的实例。您不必使用变量'this'。你可以写:
void test::print()
{
cout << x;
}