目录
1.面向对象编程中的类和对象
面向对象编程:整个程序中都是由一个一个的对象组成的!对象是由数据+算法组成!
面向过程编程:函数:数据+算法
例子:西红柿炒蛋
结构体也是一种不够彻底的面向对象编程!
回顾什么是结构体:数据类型,为了描述一类事物的属性而自定义的数据类型!
学生:
属性: 学号、姓名、性别、住址、出生日期、各科成绩(结构体只能描述属性,并不能把学生描述的活灵活现)
行为: 上课、睡觉、运行、吃饭等等 ,只能单独的封装函数,并把对应的学生结构体变量做为函数参数传进子函数,进行数据的操作!
能否把属性和行为整合起来,来描述一个学生!这样才更符合自然界的发展规律!
面向对象编程的出现,就是想要让学生更完整一些!
面向对象编程4个特性:抽象、封装、继承、多态
-
- 高频面试题目:C++中的结构体与C中结构体的区别?
《1》.C++中的结构体中是可以有函数的,而C语言中的结构体中是不可以有函数的!
《2》.C++中空结构体占1个字节的内存空间,而C语言中的结构体占0字节内存
- 高频面试题目:C++中的结构体与C中结构体的区别?
把属性和行为要整合在一起,用类这个数据类型来表示!
什么是类:为了描述一类事物的属性和行为而自定义的一种数据类型。
关键字: class
类定义的格式:
class 类名
{
public:
属性;
行为;
private:
属性;
行为;
protected:
属性;
行为;
};
对象: 用自定义的数据类型 类定义的变量!
-
- C++中的结构体与C++中类的区别?
《1》.关键字是不同的,类用class,结构体用 struct;
《2》.类中的成员默认访问权限是private的,而结构体中的成员默认是public
Private的成员在类的外部是不可访问的;public的成员在外部是可以访问的!
拓展:
类内部的成员的访问权限有三种:
private: 私有的, 在类内是可以访问的,在类外是不可以访问的
public: 公有的 在类内以及类外都是可以访问的!
protected: 受保护的!
什么是类外:{}之外,都是类外
什么是类内:{}之内,都是类内
《3》.类定义变量的初始化的方式不能按照结构体定义变量初始化的方式进行初始化
- 类定义的变量的不叫变量,叫对象
结构体定义的变量就是叫变量!
思考:
类和对象是什么关系?
类是对象的抽象, 对象是类的具体实例
电脑—类 我的电脑就是一个具体的实例
2.封装
什么是封装 (谈谈你对封装的理解):
把属性和行为提取出来(抽象)组合在一起,这就是封装, 对外提供一些接口,供外部去使用!
属性被隐藏起来了,行为被暴露出来!
总结封装的概念:
把一类事物的属性和行为提取出来,用类这种 自定义的数据类型把他们包起来,该隐藏的隐藏,该暴露的暴露!
哪些是需要隐藏的? 属性 应该放在private私有区域
哪些是需要暴露的? 行为 应该放在public 公共区域
案例: 电脑类
属性: 价格、内存、外存、品牌、颜色等等
行为: 开机、关机、上网等等
类创建对象的格式:
类名 对象名;
思考: 类实例化对象,会分配多大的内存空间?
总结: 《1》与类的数据成员(属性)是有关系,仍然要遵循字节对齐的原则
cout << sizeof(Computer) << endl; // 96
《2》类创建对象,每一个对象都有一份属于自己的数据成员,成员函数在内存中只占一块空间,它们属于这个类,不属于某一个对象,所有对象都可以使用的,是共享的!
对象访问成员的格式:
对象名.成员;
如果是指针类型,用对象名->成员。
思考: 为什么不同的对象调用同一个函数,会呈现不同对象的信息呢?
只有知道地址,就可以访问到不同的数据!
3.this指针
this什么意思: 这是、这个,它是用来保存地址的,谁的地址?就谁调用成员函数,this指的就是谁的地址!
指针是什么类型: 与类是有关系的
完整的格式: 类名 *const this;
但是在函数中并没有看到这个this指针,那是因为这个this是隐藏起来的参数!
总结:
《1》this是用来保存对象地址的!
《2》类中的成员函数都有一个隐藏的参数this,当我们通过对象去调用成员函数的时候,就已经把对象的地址赋值给了this。知道了地址,就可以访问到地址中的数据!
《3》谁调用成员函数,this指的就是谁的地址!
《4》类的成员函数中如果有访问类自己的成员,建议把this指针加上。因为当函数形参的名字和数据成员的名字一样的时候,没法区分到底是谁给谁去赋值!
不管是在类的内部还是类的外部,要访问到类的成员,必须通过对象的方式!
4.构造函数—类中特殊的成员函数
本质:是函数
什么时候调用:在创建对象的时候被调用。
作用:给对象的数据成员分配内存空间并且做初始化的操作!
谁去调用: 系统自动帮我们执行。如果我们自己没有写构造函数,系统会帮我们自己动生成一个空的构造函数!一旦自己写了构造函数,系统就不会再帮我们生成了!特别是无参数的构造函数!
构造的格式:
没有函数类型,函数名和类名一样,参数个数不限的函数! 说明构造函数可以重载!
类名(参数列表){} //参数列表可以是空的
构造函数可以有参数,通过参数给数据成员初始化:
但是构造函数所有参数都有默认值的时候,就出现了如下问题:
默认构造函数:
三种情况:
构造函数没有参数(自己定义的、系统帮我们生成的)
所有参数都有默认值,都是默认构造函数!
带参数的普通构造函数:有2个或者2个以上的参数并且不是所有参数都有默认值!
拷贝构造函数: 有一个参数,并且这个参数的类型是类类型的引用!
注意:
《1》在一个类中不能同时存在多个默认构造函数,他们之间是互斥的关系!
《2》自己写了构造函数,系统就不会帮我们生成默认的构造函数了!
《3》构造函数是可以重载的
《4》当构造函数参数有默认值的情况下,要注意二义性
请注意如下迷惑操作:
如果在类外要访问或者修改类的私有的数据成员的时候,在public区提供get开头的或者set开头的方法!
5.析构函数—类中特殊的成员函数
本质: 是函数
作用: 做对象释放前的清理工作,做资源的释放,特别是在构造中new的要在析构中去delete!
是什么时候调用:对象释放的时候(对象生命周期结束的时候)
谁去调用: 系统去调用!自己没有写,系统帮我们生成一个空的析构函数;自己写了,就不会帮我们生成了!
格式:
没有函数类型, 函数名和类名一样,函数名前面要加一个~,没有参数的!说明了析构函数是不能进行重载的!
总结: 先构造的后析构!
面试高频题目:
为什么有了malloc还需要new呢?
因malloc是C语言中标准的库函数,new是C++中的运算符,使用new去创建对象会执行构造函数!
类对象的赋值:
6、拷贝构造
拷贝构造函数格式:
类名(类类型& 对象){}
什么时候执行拷贝构造函数:
用一个已经存在的对象去初始化一个新的正在创建的对象的时候,会执行拷贝构造函数!
注意:只有一个参数,是类类型的引用!
注意: 我们没有自己写的话,系统会帮我们生成一个拷贝构造函数;如果我们自己写了,系统就不会再生成一个拷贝构造函数!
浅拷贝:单纯的数据成员值的赋值
分析原因:
如何解决:
就是让两个指针变量指向不同的内存空间。
深拷贝:
总结:
《1》什么时候进行深拷贝。什么时候进行浅拷贝?
是否有在构造函数中使用new的方式动态的分配内存空间!如果有,在进行拷贝的时候要进行深拷贝;
《2》系统帮我们生成的拷贝构造函数是浅拷贝,如要进行深拷贝,拷贝构造函数要自己去写!