关于this指针你知道什么?

  • this指针是类指针,指向对象的首地址。
  • this指针只能在成员函数中使用,在全局函数、静态成员函数中都不能使用this。
  • this指针只能在成员函数中才有定义,且存储位置会因编译器不同有不同存储位置。

this指针的用处?

一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。this作用域是类内部,当在类的非静态成员函数中访问类的非静态成员的时候(全局函数,静态函数中不能使用this指针),编译器会自动将对象本身的地址作为一个隐含参数传递给函数。

也就是,即使你没有显示的传递这个this,编译器在编译的时候也会帮你添加上,它作为非静态成员函数的隐含形参,对各个成员的访问均通过this进行。

this指针的使用

一种情况就是,在类的非静态成员函数中返回类对象本身的时候,就直接return *this;

另外一个情况就是当形参数与成员变量名相同时用于区分,如this->n = n;(不能写成n == n)

类的this指针有以下特点

(1)this只能在成员函数中使用,全局函数、静态函数都不能使用this。实际上,传入参数为当前对象地址,成员函数第一个参数为T* const this。

class B{
	public:
  int func(int p){
  	return 0;
  }
}

其中,func的原型在编译器看来是:

int func(B* const this, int p) {
	return 0;
}

(2)this在成员函数的开始构造,在成员函数结束的时候销毁。这个生命周期同任何一个函数的参数是一样的,没有任何区别。当调用一个类的成员函数时,编译器将类的指针作为函数的this参数传递进去。

B b;
b.func(10); ==>转变为 b.func(b, 10);

内存泄漏的后果?如何监测?解决方案?

1、内存泄漏

内存泄漏是指由于疏忽或者错误造成未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上消失,而是应用程序代码设计错误,从而导致失去了对这段内存的控制。

2、后果

只发生一次小的内存泄漏可能不被注意,但是泄漏大量内存的程序将会出现各种情况:例如,性能急剧下降,内存利用率逐渐使用完,从而导致程序崩溃。

3、如何排除

使用工具软件BoundsChecker,BoundsChecker是一个运行时错误检测工具,它主要定位程序运行时期发生的各种错误;

调试运行DEBUG版程序,运用以下技术:CRT(C run-time libraries)、运行时函数调用堆栈、内存泄漏时提示的内存分配序号(集成开发环境OUTPUT窗口),综合分析内存泄漏的原因,排除内存泄漏。

4、解决方法

智能指针。

5、检查、定位内存泄漏

检查方法:在main函数最后一行,加上一句_CrtDumpMemoryLeaks()。调试程序,自然关闭程序让其退出,查看输出;

例如:

{453}normal block at 0x02432CA8,868 bytes long

{}包围453就是我们需要的内存泄漏定位置,868 bytes long就是说这个地方有868比特内存没有释放。

在main函数第一行加上_CrtSetBreakAlloc(453);意思就是在申请453这块内存的位置中断。然后调试程序,程序中断了,查看调用堆栈。加上头文件#include <crtdbg.h>

在成员函数中调用delete this会出现什么问题?对象还可以使用吗?

在类对象的内存空间中,只有数据成员和虚函数表指针,并不包含代码内容,类的成员函数单独放在代码段中。在调用成员函数时,隐含传递一个this指针,让成员函数知道当前是哪个对象在调用它。当调用delete this时,类对象的内存空间被释放。在delete this之后进行的其他任何函数调用,只要不涉及到this指针的内容,都能够正常运行。一旦涉及到this指针,如操作数据成员,调用虚函数等,就会出现不可预期的问题。

为什么是不可预期的问题?

delete this之后不是释放了类对象的内存空间了么,那么这段内存应该已经还给系统,不在属于这个进程。照这个逻辑来看,应该发生指针错误,无访问权限之类的令系统崩溃的问题才对啊?这个问题牵涉到操作系统的内存管理策略。delete this释放了类对象的内存空间,但是内存空间却并不是马上被回收到系统中,可能缓冲或者其他什么原因,导致这段内存空间暂时并没有被系统回收。此时这段内存是可以访问的,你可以加上100,加上200,但是其中的值却是不确定的。当你获取数据成员,可能得到的是一串很长的未初始化的随机数;访问虚函数表,指针无效的可能性非常高,造成系统崩溃。

如果在类的析构函数中调用delete this,会发生什么?

会导致堆栈溢出。原因很简单,delete的本质就是为将被释放的内存调用一个或者多个析构函数,而析构函数里面又有delete this,那么就构成了一个无线循环,从而导致堆栈溢出,系统崩溃。

this指针调用成员变量时,堆栈会发生什么变化?

当在类的非静态成员函数访问类的非静态成员时,编译器会自动将对象的地址传给作为隐含参数传递给函数,这个隐含参数就是this指针。

即使你并没有写this指针,编译器在链接时也会加上this的,对各成员的访问都是通过this的。

例如你建立了类的多个对象时,在调用类的成员函数时,你并不知道具体是哪个对象在调用,此时你可以通过查看this指针来查看具体是哪个对象在调用。This指针首先入栈,然后成员函数的参数从右向左进行入栈,最后函数返回地址入栈。

类对象的大小受哪些因素影响?

  1. 类的非静态成员变量大小,静态成员不占据类的空间,成员函数也不占据类的空间大小;
  2. 内存对齐另外分配空间大小,类内的数据页是需要进行内存对齐操作的;
  3. 虚函数的话,会在类对象中插入一个vptr指针,加上指针大小;
  4. 当该类是某类的派生类,那么派生类继承的基类部分数据成员也会存在派生类的空间中,也会对派生类进行扩展。