1.面向过程和面向对象
C语言是面向过程的,关注的是过程,分析求解出问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象间的交互完成。
2.类的引入
C语言中,结构体只能定义变量。
C++结构体不仅能定义变量,也可以定义函数。
而C++中通常使用class关键字去替代struct关键字。
C++为什么要引入类而不是优化C语言中的结构体?
原因:C语言太过自由,数据和方法是分离的。
C语言中可以不访问接口函数,直接进行数据访问,这与原本设计师的想法大相径庭,很容易使程序崩掉。
3类的定义
C++引入了关键字class,其基本语法如下:
class为定义类的关键字,stdent为类的名字,{}中为类的主体,类结束定义时的分号。
类中的元素称为类的成员:类中的数据称为类的属性或者成员变量,类中的函数称为类的方法或者成员函数。
类的两种定义方式:
1.声明和定义全部放在类体中,需要注意:成员函数如果在类中定义,版一起有可能将其作为内联函数处理。
2.声明放在.h头文件中,类的定义放在.cpp中。
4.类的访问限定符及封装
4.1访问限定符
C++实现封装的方式:用类将对象的属性与方法结合在一起,让对象更加完善,通过访问权限选择性的将其接口提供给外部用户使用。
public(公有)
访问限定符
protected(保护)
private(私有)
【访问限定符说明】
1.pubulic修饰的成员在类外可以直接被访问。
2.protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)。
3.访问权限作用域从该访问限定符出现的位置开始知道下一个访问限定符出现为止。
4.class的默认访问权限是private,struct为public(因为struct要兼容C)。
注意:访问限定符只在编译时有用,当数据用射到内存好,没有任何访问限定符上的区别。
【面试】
问题:C++中struct和class的区别是什么?
解:C++需要兼容C语言,所以C++中struct可以当成结构体去使用。另外C++中struct还可以用于定义类。和class是定义类是一样的,区别是struct的成员默认访问方式是public,class的成员默认访问方式是private。
4.2封装
【面试题】
面向对象的三大特性:封装,继承,多态。
在类和对象阶段,我们之研究类的封装特性,那什么是封装?
封装:将数据和操作数据的方法惊醒有机结合,隐层对象的属性和实现细节,仅对外公开接口和对象进行交互。
封装本质上是一种管理。我们把不想给他人看到的成员用private/proteed封装起来,开放一些共有的成员函数队成员合理的访问。
使用实例:
5.类的作用域
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员,需要使用::作用域解析符知名成员属于哪个类域。
示例:
如果不使用::就会报错。
6.类的实例化
用类类型创建对象的过程,称为类的实例化。
1.类试试一个模型一样的东西,限定了类有那些成员,定义出一个类并没有分配实际的内存空间来储存它。
2.一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员的变量。
3.类实例化出的对象就像是现实中依据工图实际制造出的精密工件。类就是个设计图,只设计出需要什么东西,但是没有实体工件的存在,类只是一个设计,实例化出的对象才能实际储存数据,占用物理空间。
7.类对象模型
7.1计算类的大小
答案是8,为什么?
7.2类对象储存方式
猜想:
1.若对象中包含类的各个成员
缺陷:每个对象成员变量是不同的,但是会调用同一个函数,若是包含类的各个成员,当一个类创建多个对象时,每个对象都会保存一份相同的代码,浪费空间。
2.若只保存成员变量,成员函数放在公共的代码段
可以有效解决创建多个变量时,保存相同的代码,以防浪费空间。
验证猜想:
由Test1 和Test2可知,编译器采用的是猜想二,只保存成员变量,成员函数放在公共代码段。
而Test3是一个仅有成员函数的“空类”,而语法规定:没有成员变量的类对象(空类),编译时会分配1byte占位,表示对象存在过。
那么类成员所占空间就和结构体内存所占空间计算方式完全一样。
关于结构体计算方法
8.this指针
8.1this指针介绍
引入Data日期类函数
这里可以看到,Print函数能够正确的打印出不同对象的Set值,但这是怎么实现的?
C++通过this指针来解决这种对象问题。
C++编译器给每个“非静态的成员函数”增加了一个隐藏的指针函数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有操作对用户来说是透明的,用户不与要来传递,编译器自动完成。
8.2this指针的特性
1.this指针的类型:类类型* const
2.只能在“成员函数”内使用。
3.this指针本质上是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不储存this指针。
4.this指针时成员函数第一个隐含的指针形参,一般情况下由编译器通过ecx寄存器自动传递,不需要用户传递。
根据this指针的语法,将函数“还原”
会报错,原因是,你不能替编译器完成任务,这在语法上是不允许展开不全的。
补充:通过汇编代码再了解this指针
【面试题】
1.this指针存在哪里?
看上面的反汇编,可以知道this指针是放在寄存器的(编译器优化后),一般情况下时放在栈上的。
2.this指针能为空吗?
答案是:能。
验证:
思考:
这能编译成功吗?
答案:不能,程序会崩溃。
原因:P是空指针,空指针不能访问内部成员,访问_a就会报错