- 面向过程和面向对象初步认识
C语言是面向过程,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分为不同的对象,考对象之间的交互完成。
举例:
设计简单的外卖系统:
面向过程:关注实现下单,接单,送餐这些过程。 体现到代码层面--方法/函数。
面向对象:关注实现类对象以及对象间的关系,用户,商家,骑手,以及他们之间的关系。体现到代码层面--类的设计以及类之间 的关系。
C++中类的创建:
struct定义的结构体仍然可以被C++兼容 在C++中可以直接用Student类型名定义对象; | ||
面向对象的三大特性:封装,继承,多态 封装:数据和方法都放在类里面。 访问限定 符:public(公有) protected(保护) private( 私有) class默认访问限定符 是private,struct默认 访问限定符是public; | ||
类成员变量一般都是私有的,通过共有的成员 函数来改变成员变量。 外部引用时,需要带上对象名.Init才能调用函 | ||
类的大小:对象中存了成员变量,但是没有存成员函数。 原因:因为成员函数是公共的,存储会浪费空间,因此函数会放在公共区
域,因此计算类的大小只需要考虑类的成员变量和内存对齐。 注意:空类的大小是1字节; 类的声明不占用内存,会储存在公共代
码段,只有类实例化之后,类才占用共建。
使用Date来了解对象:
this指针: this指针在调用和定义过程中,不能出现,在成员函数内部可以使用。
在通过公共函数init将时间传给内部私有成员,其实在传递过程过,有一个隐藏的this指针来指向当前类的成员,再进入公共函数时, 类的地址传给了隐藏的this指针。
在类中有六个默认函数:
| |
| |
值得注意的是:拷贝构造是将一个已经实例化的对象赋值给一 |
在了解赋值运算符重载之前先了解运算符重载
运算符重载: 注意“ .* sizeof ? : . :: 这五个运算符不能重载”
运算符重载不能添加新的运算符并且在重载时 不能改变运算符的意义,因此重载时的参数数 |
类的运算符重载定义在类的内部,可以解决访
问限定符私有成员外部无法访问的问题,调用 方法如下:
d1>d2,编译器先在类中查找运算符重载,再查找全局,如果都找不到则报错。 |
- 赋值运算符重载:需要注意参数类型,返回类型,以及返回*this,默认的赋值重载函数和默认的拷贝构造一样将内置类型进行 字节序的浅拷贝,自定义类型调用其赋值重载函数
总结:构造函数负责初始化,析构函数负责释 | ||
Date运算符重载: 日期运算 ++ += + 的重载:
前置++和后置++为了在重载函数中识别,后 置++函数的参数类 | |
例题: 左图的代码,一共会调用9次拷贝构造,但是 编译器会进行优化,将同一行代码的构造和拷贝构造合并,所以减少了两次拷贝构造,只有 七次。 |
流插入运算符在类里面重载时,直接定义在类 里面,会导致第一个参数时*this而不是流插入 类型,因此定义友元函数在类中,即可 |
初始化列表:
初始化列表是类对对象成员进行定义的地方, 进行初始化。 在这里可以对内置成员进行初始化,以及常量, 自定义类型的初始化,但是默认构造函数函数 体内无法对常量和自定义类型进行赋值。 需要在函数体外进行初始化,如下图: | ||
在对自定义类型进行初始化赋值时,一般使用初始化列表,因为初始化列表的效率更快,需要调用的构造函数次数更少
通过构造函数进行初始化会 在构造函数定义aa时调用一 | |
而使用初始化列表则直接进 |
关于结构体内初始化的顺序,如下题:
其实再进行初始化过程中, 初始化顺序是按照变量声明 的顺序进行初始化,因此先 所以再进行初始化时,书写 顺序与声明顺序保持一致。 | ||
C++中的隐式类型转换,explicit可以禁止隐士 类型转换。 | ||
友元:分为友元函数和友元类,友元是一种突破了封装的方式,提供了便利,但是破坏了封装,所以友元不适合多用。
友元函数属于全局函数,但是可以访问私有成员,友元函数不支持const,且可以写在任何位置,不受访问限定符的影响。
友元类:这个类的所有成员函数都是该类的友元函数。
内部类:在一个类A当中定义定外一个类B。
重点: 内部类B和在全局定义是基本一样的,只是他受外部类A的影响,即只能通过A找到B A::B bb, 以及B会收到A访问限定符的影响,B天生就是A的友元,B可以访问A的私有,但是A不能访问B的私有。