浅谈struct与class,深入理解this指针

struct与class

  • struct与class有什么区别
    C++兼容c,所以struct可以继续用于在c++中做结构体定义多个变量,同时struct与class用来定义类,它们不仅可以定义变量,也可以定义函数。struct中无论是成员变量还是成员函数都是public,而在class中默认为private。
    在编写C++代码中我们更多的用class来定义类。

    类的作用限定符

    public(公有)
    private(私有)
    protected(保护)

    类的作用域

    类规定了一个作用域,成员都在这个作用域里,如果需要在类外定义成员就需要加类的作用限定符。比如像我们平常练习,声明和定义在一起,像这样:
    在这里插入图片描述
    但实际在工程中与C类似,需要声明,定义分离,在.h文件中写声明,.cpp文件中写定义。
    在这里插入图片描述
    showInfo()加上了类的作用域解析符 person::showinfo

类对象大小的计算

这个a的大小是12,并没有算成员函数的大小

在这里插入图片描述
按我们开始想的那样,岂不是每次实例化个对象里面都存储着成员变量和成员函数,那样花费太大了,那成员函数在哪里,实际上他在常量区,C++叫代码段。这里的代码段并不是指我们所编写的代码,是我们所写的代码转换成指令,我们编的代码本质上属于文件,存储在硬盘当中。
在这里插入图片描述

那假如成员函数,成员变量都没有或者只有成员函数大小是多少呢?0吗?
这种类叫空类,它实际留了一个字节作为占位,实例化对象后表示对象存在

  • 几道面试题复习
    在这里插入图片描述

this指针

this指针的引出

在这里插入图片描述
在这里插入图片描述

前面可知成员函数是在公共的代码段,那么编译器是怎么区别是谁调用的Init函数呢?
d1.init(x,x,x); d2.init(x,x,x);区分的吗?
不是的,假如成员变量是public,上述代码和d1.month,d2.month不一样,后者的意思是调用d1,d2对象内的month。
d1.init(x,x,x); d2.init(x,x,x);指的是到这个d1,d2是Data类,到类中寻找存储在代码段的成员方法。

本质上d1.init(x,x,x); d2.init(x,x,x);等价于 call Init(地址)
这两个相同是怎么区分的呢?

其实是C++编译器给每一个非静态的成员函数增加了一个隐藏的指针参数,这个指针指向了调用该成员函数的对象,成员函数内部对该对象成员变量进行操作都是由这个指针进行操作,只不过对用户透明,编译器自动完成。
而且自己不能手动加Data* this,是编译器自动加好的。所以我们可以用他,实际也用了只是不显示,只是这里把他写出来。
在这里插入图片描述
d1.init(x,x,x);d2.init(x,x,x);会分别打印出d1,d2对象的地址。
这两道题有助于我们更好地了解this指针

深入理解this指针

面试题1:
this指针存在哪里?
this指针是个形参,按理说应该存在栈中,但是通过反汇编看到,形参从右向左push入栈,第四个参数this指针存到了寄存器中。
在这里插入图片描述
在这里插入图片描述

面试题2:
this指针可以为NULL吗?
在这里插入图片描述
像之前我们定义的是

A p;
p.print();    而p.print()传的实参实际上是p.print(&p),
                定义有个隐藏的形参是 p.print(A* this)
               所以this形参接收的是实参&p,也就是他的地址

而在下图p是一个类指针。就表示地址。所以this直接就接收的是p(类比上面代码)。
说明清楚后把上面的问题分成两个子问题,下面这段代码会崩溃吗?
在这里插入图片描述
p是一个类指针,与调用成员变量意思不同,p->PrintA();的意思是到A这个类中去寻找存储在代码段中的成员方法。上面说到这个由于他是个类指针,所以直接传的是p,
p->PrintA(A* this);接收到p, 所以this变成了nullptr,这个函数里调用了成员变量_a

cout<<_a<<endl;等价于cout<<this._a<<endl

而this是nullptr此时对空指针进行了操作就会崩溃。
再看另一个子问题。

在这里插入图片描述
show函数里面是没有调用任何成员变量的,所以没有对空指针进行操作自然就不会崩溃了。

猜你喜欢

转载自blog.csdn.net/qq_45928272/article/details/113617193
今日推荐