C++中this指针

this指针

  • this指针的类型是是类类型* const,比如class B,this指针的类型就是B* const
  • this指针的作用域仅限于类内部 * this指针并不是对象的一部分,sizeof的时候不会算上this指针的大小
  • this指针在非静态成员函数中使用,其他任何函数都不可以
  • this指针是非静态类成员函数的第一个默认参数,且自动隐蔽,编译器自动维护传递,类编写者不能显示传递
  • 静态成员函数不会隐式地传递一个this指针,且在静态成员函数中不能访问非静态的成员变量,只可以访问同样静态的成员变量,而非静态成员函数既可以访问静态成员变量,也可以访问非静态成员变量。
  • this指针是可以为空的,this指针为空之后,就不可以通过this访问非静态成员变量了,即假设a是A类的成员变量,this为空之后,this->a这样的操作就不可能的,就是访问空指针
  • 既然this指针可以为空,那么this为什么是指针,而不是引用就可以知道了。指针可以为空,即有空指针,但是不存在空引用的概念。(但实际上是,在this指针概念提出来的时候,还没有引用的概念)
class CNullPointCall
{
public:
        static void Test1();//静态的成员函数Test1
        void Test2();
        void Test3(int iTest);
        void Test4();
private:
        static int m_iStatic;?//静态的成员变量,需要在类外初始化
        int m_iTest;//非静态的成员变量
};

int CNullPointCall::m_iStatic = 0;//类外初始化静态的成员变量
void CNullPointCall::Test1()
{
        cout << m_iStatic << endl;//打印一个静态的成员变量的值
}
void CNullPointCall::Test2()
{
        cout << "Very Cool!" << endl;//只是打印一句very cool
}
void CNullPointCall::Test3(int iTest)
{
        cout << iTest << endl;//打印传给该函数的参数
}
void CNullPointCall::Test4()
{
        cout << m_iTest << endl;//打印一个非静态成员变量的值,相当于this->m_iTest
}
int main()
{
        //以下四个调用只有Test4()用到了this指针,1、2、3都是可以正确执行的
        CNullPointCall *pNull = NULL; //没错,就是给指针赋值为空,相当于this为空了
        pNull->Test1(); // 相当于CNullPointCall::Test1(),访问静态成员函数
        pNull->Test2(); // 直接输出一句话
        pNull->Test3(13); // 输出传进去的参数
        pNull->Test4(); // 输出非静态的成员变量,this->m_iTest,this指针为空,会出错
        return 0;
}

_thiscall调用约定
它不是关键字,它是C++类成员函数缺省的调用约定,通过这种约定,让this指针成为成员函数的第一个参数

  • _thiscall只能用在类的成员函数上
  • 类成员函数的参数从右向左被压入栈
  • 如果参数个数确定,this指针通过ecx传递给被调用者;如果参数不确定,this指针在所有参数被压栈后压入堆栈
  • 对参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈

来一段代码感受一下

class A
{
public:
    int funcontion1(int a, int b);
    int funcontion2(int a,...);//在参数列表后面加三个'.'表示可以有不定的参数
};
int A::funcontion1(int a, int b)
{
    return a + b;
}
int A::funcontion2(int a, ...)//a表示传的参数的个数
{
    va_list ap;//用于获取不确定的参数个数
    va_start(ap, a);//获取第一个可选参数地址
    int i;
    int result = 0;
    for (int i = 0; i < a; ++i)
    {
        result += va_arg(ap, int);//获取下一个参数地址
    }
    return result;
}
int main()
{
    A a;
    a.funcontion1(1, 2);
    a.funcontion2(3, 1, 2, 3);
    return 0;
}

a.funcontion1(1, 2);
00BA18B8  push        2 
00BA18BA  push        1 //这两部表示参数是从右向左被压入栈的
00BA18BC  lea           ecx,[a]//这里引入了this指针  
00BA18BF  call        A::funcontion1 (0BA13FCh) //注意,这里this没有被压入栈中


a.funcontion2(3, 1, 2, 3);
00BA18C4  push        3 
00BA18C6  push        2 
00BA18C8  push        1 
00BA18CA  push        3 
00BA18CC  lea         eax,[a] //这里引入this指针
00BA18CF  push        eax //这一步,this指针被压入了栈中
00BA18D0  call        A::funcontion2 (0BA1401h) 
00BA18D5  add         esp,14h

关于this指针的相关问题

  • 何时创建:在成员函数的开始执行前构造的,在成员函数的执行结束后清除
  • 存放于何处:this指针会因编译器的不同,而放置的位置不同,可能是栈,也可能是寄存器,甚至是全局变量
  • 如何访问类中的变量的:this想当于类的指针,如果是结构,那this就是结构的指针了
  • 知道一个对象this指针的位置能否直接使用:this指针只有在类成员函数内部才有定义,因此获得一个对象后,也不能通过对象使用this指针,因此也无法知道this指针的位置(只有在成员函数里才有this指针的位置,且在成员函数执行结束后就清除了)。
  • 每个类编译后,是否创建一个类中函数表来保存函数指针,以便来调用函数
    普通的类函数都不会创建一个函数表来保存函数指针,只有虚函数才会被放到函数表中。
    但即便是虚函数,如果编译器知道调用的是哪个函数,都会直接去调用该函数,而不会通过函数表中的指针间接调用
  • this指针如何传递给类中的参数的:大多数编译器通过exc寄存器传递this指针,在调用函数之前,编译器会把对应的对象的地址放到exc寄存器中,而this指针就是指向这个地址
  • 为什么this指针不能再静态函数中使用:静态成员函数并不是针对某个类的实例对象,而是属于整个类的,为所有的对象实例所共有。它在作用域的范围内是全局的,独立于对象之外,并且只对类内部的静态成员变量做操作。在实例化一个类的对象的时候,里面不存在静态成员。this是类的实例的指针,因此不能用来操作实例之外的静态成员函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值