2021.1.7C++第二课
今日任务 : 1.面型对象总结 2.前期理论知识为主,后期实际操作为主
上节课回顾:对象是类的实例化,对象是对现实世界的映射,类是一种数据类型
- 我们是设计了一个类,然后定义了一个对象. 类是我们设计的产物,设计类并不意味着要开辟空间,定义对象才会开辟空间
- 全局对象和全局变量分配到了 数据区
- 在程序编译后开始运行,凡是在函数之外定义的全在数据区,凡是在函数之内定义的全在栈区,凡是malloc,new,free ,delete出来的全在堆区
- 在类中定义的变量默认为私有成员
- 结构体只能封装数据,类可以封装数据和函数
- 属性值决定了你当前的状态。一般函数是类内声明类外定义(如果是在类外定义请注意要在函数名前加类名+作用域解析运算符)如果函数实在类内声明和定义的就是默认的内联函数,如果是类内声明类外定义则不是默认的内联函数,如果想成为内联函数需要在声明和定义时都要在最前边先写inline
- C++的函数分类两个类型:全局函数,类中函数
- 不同方式定义的对象生存期不同 1.全局对象{在函数外直接定义的对象}和局部对象{函数内部定义的对象}都是由系统控制的生命周期,而只有你自己new出来的对象在堆区中才会由你自己掌控
- 在主函数定义的局部变量如果未初始化就是随机值,而在全局对象中的全局变量若未初始化则放入未初始化区域(bss)全部自动初始化为0.
- data 区又分为 已初始化区域和未初始化区域 (bss,区域内全部为0000)
对象模型讨论
1.编译器在编译类的时候会编译三次
- 首先第一次把我们的数据成员的属性(类型和名称)记录在案
- 第二次扫描函数原型 函数原型包括:返回类型,函数名,参数类型,参数个数
- 第三次扫描最重要就是对函数进行改写》》改写前 void delete(const char*name,int amunt) 改写后 void delete(GGood const *this,const char*name,int amunt) 加入一个指针 类名 const *this
int getnumber() 》》》 int getnumber(GGood const *this)
- this 指针非常重要 掌握其使用就相当于掌握里面向对象诀窍的百分之40,this指针只有在你的成员方法也就是成员函数被调用时才显现,所谓this指针就是你当前本身对象的地址
- 空间和对象的分离》》》 有空间不一定有对象
我们一定要注意对象和空间的分离,首先我们要知道我们自己是不能够调用构造函数的,所以在主函数运行是,你定义了一个对象后(其实此时只是申请了一个空间),之后系统自动调用构造函数(你自己定义的构造函数或者系统自带的构造函数)这样就实现了对象的初始化。而如果你用malloc去申请了一个空间,然后说是要定义对象,这时候你就会想你已经有空间了,那么再调用一个构造函数构造一个对象不就完事了,但是我们已经说过了构造函数我们不能自己调用,你如果去定义一个对象,那么人家自己就申请空间调用构造函数了,你申请的空间完全没用。所以用malloc去定义对象是自相矛盾的。而new则不同一般用new 就是 BOOK *p= new BOOK; 这个意思是在data区new一个空间然后调用构造函数完成定义对象,之后在栈区定义一个 指向这个空间的指针。 之前我们说过全局对象的生存期我们不能控制,然后局部对象的生存期我们只能决定他的死(调用析构函数),而你自己在堆区申请的空间得到的对象的生死则都是由你控制的,一般就是 new 和delete。
-
构造函数有三种用途: 创建对象 初始化对象中的属性 类型转换
-
图示为 无参构造函数,缺省构造函数,以及构造函数类内声明类外定义
静态函数和友元函数 参数中不隐藏 this指针 全局函数更没有this指针
注 我们不能这样构造对象 类名 变量名(); 《《 只要是你有括号了就一定要有参数,不然编译器在编译时会认为你这是一个函数 而不是一个对象定义 因为函数 定义一般是 类型名 函数名();
你不能决定你的生但你可以决定你的死----我们不可以自己调用构造函数和但可以自己调用析构函数
生而不同----不同的构造函数
int *p= new int 调用伪构造函数