C++深入浅出讲解隐藏this指针的用法

 更新时间:2022年05月16日 11:18:30   作者:小白又菜  
在C++中,每一个对象都能通过this指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象

本篇文章我们将一起讨论在有趣的知识点--隐藏的this指针。本篇我们要使用到之前我们所学习到的C++类与对象,如果有各位小伙伴还不曾了解类与对象的简单思想,可以访问上篇:C++深入讲解类与对象之OOP面向对象编程与封装

在之后的学习中,我们将认识一个新的类:日期类Date。正如我们所想的那样,传入一个日期,我们可以输出我们所输入的日期。

1.this指针的引出

那我们首先来看一下,这段代码会输出什么结果呢?

class Date
{
public:
	void Display()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	void SetDate(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};
int main()
{
	Date d1, d2;
	d1.SetDate(2022, 5, 11);
	d2.SetDate(2022, 5, 12);
	d1.Display();
	d2.Display();
	return 0;
}

输出结果:

我们首先可以通过汇编来看看,d1,d2调用的函数是否相同。

我们可以发现,最终打印的时候调用的Display()是同一个函数,那么既然d1,d2调用的都是同一个函数,编译器如何知道d1是2022-5-11,d2是2022-5-12呢?Display()都访问的_year,_month,_day。而且去公共代码区访问的Display(),这是为什么呢?

这是因为C++在这段代码中做出手脚,C++在这里增加了一个this指针,这里是因为Display会增加一个this形参。C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

在调用的时候也传的是各自的地址。这样就十分清晰明了了。这就是隐含的this指针

注意:我们不能显示的写出来,因为他是隐含的,我们不能抢了编译器的活。但是我们可以直接在类里面用。

2.this指针的特性

在真正的编译器中this指针的用const修饰的,this指针本身是不能被修改的,但是内容是可以修改的。并且我们是可以使用的

我们可以在类中打印一下this指针,并且我们在也同时打印一下d1和d2的地址,我们来看一下:

class Date
{
public:
	void Display()
	{
        //使用this指针
		cout << this << endl;
		cout << _year << "-" << _month << "-" << _day << endl;
	}	
	void SetDate(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};
int main()
{
	Date d1, d2;
	cout <<"d1:"<< & d1 << endl;
	cout <<"d2:"<< & d2 << endl;
	d1.SetDate(2022, 5, 11);
	d2.SetDate(2022, 5, 12);
	d1.Display();
	d2.Display();
	return 0;
}

运行结果:

并且我们还能这样写,但是我们不能显示的写出Date* this。

我们接下来再看看this指针是不能修改的,大家看下面这个能过吗?答案肯定是不能的,因为this是被const修饰的,不能修改this指针的。

我们会发现 编译器也会报错:error C2106: “=”: 左操作数必须为左值

this指针的特性总结:

1. this指针的类型:类类型* const。

2. 只能在“成员函数”的内部使用。

3. this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。

4. this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。

3.练习一下

(1)下面的程序的运行结果是? A.编译报错 B.运行崩溃 C.正常运行

class A
{
public:
	void Show()
	{
		cout << "show()" << endl;
	}
private:
	int _a;
};
 
int main()
{
	A* p = nullptr;
	p->Show();
	return 0;
}

结果:C

原因:Show()函数是存在公共代码区中,编译的时候在公共代码区中找到这个函数,和普通的函数调用是一样的,只需要call函数地址就行。我们发现这里p是空指针,传过去的this指针只是接收了p的空指针,就类似于this指针被初始化为空指针。这是允许的。

(2)下面的程序的运行结果是? A.编译报错 B.运行崩溃 C.正常运行

class B
{
public:
	void PrintA()
	{
		cout << _a << endl;
	}
private:
	int _a;
};
int main()
{
	B* p2 = nullptr;
	p2->PrintA();
	return 0;
}

结果:B

原因:此程序崩溃是在PrintA()中,会隐含一个this->_a,而this指针是一个空指针,访问this指针_a的位置,就要对空指针进行解引用,此时就会崩溃。我们也可通过调试观察到。

(3)this指针是存在哪里的?

a.栈 b.堆 c.静态区 d.常量区

答案:a

解释:this指针是个形参,形参是在函数的栈桢里,在函数的栈桢里面的变量是属于栈中的。

有时编译器会使用寄存器对其进行优化,this指针会存在寄存器中。

到此这篇关于C++深入浅出讲解隐藏this指针的用法的文章就介绍到这了,更多相关C++this指针内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一篇文章彻底搞懂C++常见容器

    一篇文章彻底搞懂C++常见容器

    容器就是一些特定类型对象的集合,容器可以分为顺序容器和关联容器,下面这篇文章主要给大家介绍了关于C++常见容器的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • c++素数筛选法

    c++素数筛选法

    本文讲的是筛选法的C++实现, 筛选法又称筛法,是求不超过自然数N(N&gt;1)的所有质数的一种方法。据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274~194年)发明的,又称埃拉托斯特尼筛子。
    2017-05-05
  • MFC对话框中添加状态栏的方法

    MFC对话框中添加状态栏的方法

    这篇文章主要介绍了MFC对话框中添加状态栏的方法,实例分析了MFC对话框添加状态栏所涉及的相关成员变量与事件实现技巧,需要的朋友可以参考下
    2015-07-07
  • Qt开发实现跨窗口信号槽通信

    Qt开发实现跨窗口信号槽通信

    这篇文章主要为大家详细介绍了Qt开发实现跨窗口信号槽通信,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C语言实现简单的抽奖系统

    C语言实现简单的抽奖系统

    这篇文章主要为大家详细介绍了C语言实现简单的抽奖系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • C语言由浅入深讲解线程的定义

    C语言由浅入深讲解线程的定义

    这篇文章主要介绍了C语言中线程的基础知识,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • C语言实现控制台五子棋小游戏

    C语言实现控制台五子棋小游戏

    这篇文章主要为大家详细介绍了C语言实现控制台五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 深入Main函数中的参数argc,argv的使用详解

    深入Main函数中的参数argc,argv的使用详解

    本篇文章是对Main函数中的参数argc,argv的使用进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 讲解C++中的枚举类型以及声明新类型的方法

    讲解C++中的枚举类型以及声明新类型的方法

    这篇文章主要介绍了讲解C++中的枚举类型以及声明新类型的方法,是C预言入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • 12个关于C语言的有趣问答

    12个关于C语言的有趣问答

    这篇文章主要介绍了12个关于C语言的有趣问答,有助于读者加深对C语言程序设计的理解,需要的朋友可以参考下
    2014-07-07

最新评论