C++ this指针
个人主页:Jason_from_China-CSDN博客
所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客
概念概述
- Date 类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当 d1 调用 Init 和 Print 函数时,该函数是如何知道应该访问的是 d1 对象还是 d2 对象呢?那么这里就要看到 C++ 给了一个隐含的 this 指针解决这里的问题。
- 编译器编译后,类的成员函数默认都会在形参第一个位置,增加一个当前类类型的指针,叫做 this 指针。比如 Date 类的 Init 的真实原型为,void Init (Date* const this, int year, int month, int day)。
- 类的成员函数中访问成员变量,本质都是通过 this 指针访问的,如 Init 函数中给_year 赋值,this-> _year = year。
- C++ 规定不能在实参和形参的位置显式的写 this 指针 (编译时编译器会处理),但是可以在函数体内显式使用 this 指针。
this指针的具体使用
举例1:
//.h文件 class Date { public://公有 //构造函数(全缺省构造函数) Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } void Print2(); void Print1() { cout <<"类里面实现函数调用:" << _year << "/" << _month << "/" << _day << endl; } private: //私有成员函数变量 int _year; int _month; int _day; }; //类外面实现函数调用 //void Date::Print2(Date* const this) void Date::Print2() { cout << "类外面实现函数调用:" << _year << "/" << _month << "/" << _day << endl; //完全书写 std::cout << "类外面实现函数调用:" << this->_year << "/" << this->_month << "/" << this->_day << std::endl; } //.cpp的实现 #include"test.h" int main() { cout << "类的定义格式:" << endl; //初始化需要默认构造函数,默认构造函数是编译器自带的初始化,以及全缺省构造函数,以及无参数构造函数 //对象1 Date d1; d1.Print1();//这里等同于 d1.Print1(&d1);但是这里是&是不传递参数的,也是不会写的,只是类似于传递参数由this接收参数 //对象2 Date d2(2, 2, 2); d2.Print2();//这里等同于 d1.Print1(&d1);但是这里是&是不传递参数的,也是不会写的,只是类似于传递参数由this接收参数 return 0; }
简单的说就是调用函数的时候,是有一个this指针指向对象的,因为C++支持函数重载,编译器会自己找到匹配的对象,这里如何找到,就是依靠this指针
举例2:
注意事项
注意事项1:
函数传参的时候,不支持显示写
注意事项2:
使用的时候支持显示写,但是不写也会直接默认存在
注意事项3:
静态成员函数是没有this指针的
在C++中,静态成员函数是与类相关联的,而不是与类的任何特定对象相关联。因此,静态成员函数不依赖于任何对象实例,它们可以在没有创建类的对象的情况下被调用。由于静态成员函数不与任何特定的对象实例相关联,它们无法访问类的非静态成员变量或成员函数,因为这些成员需要通过 this 指针来访问。
静态成员函数是用
static
修饰的成员函数。静态成员函数(静态成员函数是用
static
修饰的成员函数。):
- 静态成员函数不属于特定的对象,它是类的一部分而不是对象的一部分。
- 可以通过类名直接调用,无需通过对象来调用,例如
ClassName::staticFunctionName()
。- 静态成员函数不能访问非静态成员变量,因为它没有
this
指针来指向特定的对象。但可以访问静态成员变量。
C++内存区域划分
声明:
这里是知识是很重要的,以我的水平是没有办法很好的讲解出来,所以作为了解放到最下面,这个知识主要是函数栈帧的知识,感兴趣的伙伴可以去查找一下,或者单纯的了解一下也是没有什么问题的
在 C++ 中,内存主要分为以下几个区域:
栈(Stack):
- 存储局部变量、函数参数等。
- 由编译器自动管理内存的分配和释放。当函数被调用时,为函数的局部变量和参数在栈上分配空间;当函数返回时,这些空间被自动释放。
- 空间相对较小,增长方向是从高地址向低地址。
堆(Heap):
- 用于动态分配内存,通过
new
、malloc
等操作符进行分配,通过delete
、free
等进行释放。- 程序员需要手动管理堆内存的分配和释放,若管理不当可能会导致内存泄漏或悬空指针等问题。
- 空间相对较大,可根据需要动态增长。
全局 / 静态存储区:
- 存储全局变量和静态变量。
- 全局变量在程序启动时分配内存,在程序结束时释放;静态变量根据其作用域在不同的时间点分配和释放内存。
常量存储区:
- 存储常量,如字符串常量、常量数值等。
- 这些常量在程序运行期间不能被修改。
代码区:
- 存储程序的二进制代码。
- 这个区域通常是只读的,防止程序的代码被意外修改。
- 这里我找了这两张图,方便了解