【c++学习笔记】this指针

本文深入探讨了C++中的this指针概念及其特性,解释了它是如何在成员函数内部引用当前对象的,并对比了C语言中处理对象的方式。同时,文章还介绍了_thiscall和_cdecl两种不同的调用约定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:this指针是什么?

  • 在上一篇博客当中介绍了c++中类的概念,类中可以定义成员函数,但是在类的对象模型中,并不是按照我们想的那样,类的实例对象中包含成员变量和成员函数,或者指向成员函数的指针,而是只保存非静态成员变量,那么不妨想想下面的代码:
#include <iostream>
using namespace std;


class Date
{
public:
    void SetDate(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    void PrintDate()
    {
        cout << _year << "/" << _month << "/" << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1, d2, d3;
    d1.SetDate(2018, 6, 15);
    d2.SetDate(2011, 6, 21);
    d3.SetDate(1996, 9, 1);

    d1.PrintDate();
    d2.PrintDate();
    d3.PrintDate();

    return 0;
}

这里写图片描述

  • 用Date类分别创建三个对象d1,d2,d3,因为这三个对象的模型中只包含他们的非静态成员变量,成员函数只有一份,函数中没有区别不同对象的任何标志,但是这里d1调用SetDate函数, 函数怎么就知道是设置d1的信息,而不是设置d2,从结果中我们也知道d1调用确实设置的是d1的信息。
  • 要解决这个问题,我们再用c语言实现上述过程
#include <stdio.h>

struct Date
{
    int _year;
    int _month;
    int _day;
};

void SetDate(struct Date* d, int year, int month, int day)
{
    d->_year = year;
    d->_month = month;
    d->_day = day;
}

void PrintDate(struct Date* d)
{
    printf("%d/%d/%d\n", d->_year, d->_month, d->_day);
}

int main()
{
    struct Date d1, d2, d3;
    SetDate(&d1, 2018, 6, 15);//要设置哪个对象就必须将对象的地址传进去
    SetDate(&d2, 2011, 6, 21);
    SetDate(&d3, 1996, 9, 1);

    PrintDate(&d1);
    PrintDate(&d2);
    PrintDate(&d3);

    return 0;
}
  • 从上面的代码中可以看到,函数如果要操作类的对象,就必须将类的对象的地址传进来,否则不能对类的实例对象进行修改,实际上c++也是用同样的方法,成员函数也有一个隐藏的指针,这个指针就是this指针,指向了调用该函数的对象。

二:this指针特性

  • this指针的类型,类类型* const,即不能改变指针指向
  • this指针并不是对象本身的一部分(也就是在内存中不在一起存储),不影响sizeof的大小
  • this指针是“类成员函数”的第一个默认隐含参数,编译器自动维护传递,编写者不能显示传递

三:_thiscall和 _cdecl调用约定特点:

1._thiscall

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

2._cdecl

__cdecl 是 C Declaration 的缩写,表示 C 和 C++ 默认的函数调用约定。是C/C++和MFCX的默认调用约定。

  • 按从右至左的顺序压参数入栈、。
  • 由调用者把参数弹出栈。切记:对于传送参数的内存栈是由调用者来维护的,返回值在EAX中。因此对于像printf这样可变参数的函数必须用这种约定。
  • 编译器在编译的时候对这种调用规则的函数生成修饰名的时候,在输出函数名前加上一个下划线前缀,格式为_function。如函数int add(int a, int b)的修饰名是_add。

更为具体的调用约定介绍可参考:https://blog.youkuaiyun.com/virgofarm/article/details/80706247

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值