再C++中,我们使用类定义自己的数据类型。通过定义新的类型来反映待解决的问题中的各种概念,可以使我们更容易编写,调试和修改程序。
类定义格式
首先类的定义格式和结构体差不多,而结构体的那一套语法也可以在C++中使用。class是定义类的关键子,然后{}是主体,类结束时的分号也不能省略,这和结构体差不多。只不过,现在哦我们可以在类里面定义函数了。
像这样,我们就定义好了一个日期类。可以发现,我们把成员变量都定义了一个关键字private,这在英语里面是个人的私人的意思。到了C++中,这里也是私有的意思。意思就是不能在类外面访问,只能在类里面的函数访问。我们把函数设成了public(公有的),就是我们定义的类的函数可以被外部访问。
为了区分成员变量,我们把成员变量一般都使用下划线加变量名来定义,所以我定义的成员变量都有一个下划线。
C++中也可以定义类,C++中兼容C的struct的用法,并新增了它有class的能力,只是如果没有给它的成员加上访问限定符时,它会默认为公有的。一般情况下,我们还是推荐使用class定义类。
内联函数(inline)
将函数定义为内联函数,通常就是将它在每个调用点上“内联地展开”。它的作用是避免函数调用的开销。首先我们知道,调用函数是在栈上开辟了一段空间,然后再执行。对于一些频繁操作的函数来说,我们就可以把它设置成为内联函数,让它在调用的位置展开,就节省了很多时间。
但是,内联函数一般都只用于优化规模较小,流程直接,频繁调用的函数。比如我们的一些交换函数等等,这些函数比较简单,就可以设置为内联函数。但是当我们不小心把一个很复杂的函数设置成为了内联函数的时候,怎么办呢? 其实内联说明只是向编辑器发出一个请求,编译器可以忽略掉这个请求。编译器可以自动识别一些函数是否能编译成内联函数。
类域
类定义了一个新的作用域,类的所有成员都在类中。但是我们在类中定义函数的时候还是经常想把函数定义放在类外面。这个时候我们就需要去使用作用域操作符::去声明函数属于哪一个类。
看上面的代码,我们只在类里面声明了初始化函数Init,并没有定义它,当我们在类外面去定义它的时候就需要用到作用域访问符::。它是由两个冒号组成。
实例化概念
用类在物理内存中创建对象的过程,叫做类的实例化对象。
类是对事物的一种抽象描述,在我们定义它的时候,它还没有被创造出来,是一个模型化的东西,限定了类有哪些成员变量,可以进行什么操作。用类实例化出对象后,才会产生空间消耗。
举个例子:实例化对象就好比我们再造房子,房子的布局,大小,房间等都在图纸上画好了,但是房子还没有建造出来,不能够住人,当实例化对象之后,就好比建好了房子,一个真正的实物及u出现了,才产生空间是消耗。
成员的大小
当我们定义了一个类之后,我们要怎样计算它的大小呢?我们只需要知道,类里面定义的函数都是放在公共区域的,因此当我们在计算类的大小时,只需要计算类成员变量的大小就行了。然后这里的类成员大小的计算方法和C语言中结构体的计算方法相同,我在前面已经讲过了,大家可以跳转下面的链接去看一看。
https://mp.csdn.net/mp_blog/creation/editor/137196424
this指针
Date类中有两个函数,当我们调用两个函数的时候,它是怎么区分d1和d2这两个对象的呢?在这里面,隐藏着一个this指针,它们分别指向d1和d2。然后调用函数的时候,再使用this指针去进行赋值操作。
当然,我们再定义函数的时候,不用使用this指针,编译器会自动加上的。
C++中规定不能在形参和实参的位置写this指针,只能在函数体内使用this指针,否则编译器会报错。
根据前面学习的知识,我们可以看一看上面这道题选什么。首先我们分析,我们定义了一个A类型的指针为空,然后我们去调用它的函数,是否能成功呢?答案是能。所以说这道题选择B。因为我们前面说过,我们的函数是放在公共区域的,我们对p进行解引用是访问的公共空间,并没有去访问A所指向的空间,所以程序不会崩溃。至于编译报错,我们的语法都没有什么问题,所以编译器并不会报错。
现在这个情况下就会报错了,因为我们在Print函数中增加了一行代码去访问p中的_a,它会解引用去访问空指针的空间,空指针是不允许被访问的,所以程序会崩溃。
第三个问题答案选A。这和编译器有关系,也有可能存在寄存器中。