对象 内存单元的起始地址,就是对象的指针;
和普通变量的指针是类似的。
int *ptr = &mow.hour;
成员函数指针
使用类成员指针(.*)和(->*)
this 指针
什么时候需要编写析构函数
往往是 内部有指针,且(一定)用的是深复制,即,自己编写的**复制构造函数;**往往还要有 赋值运算符的重载; 这被称为 析构函数三法则。
她们三个几乎同时存在。
【注意】:构造函数 和 析构函数的调用,类似于栈的先进后出
与 构造函数是对应的概念:
在创建对象的时候,会调用构造函数;
在对象运行超出作用域时,会调用析构函数。
【注】:1.没有返回类型,没有函数参数
2.不能重载,只有一个析构函数。
main()函数,return 0;语句执行之后,pt1的作用域就结束了,此时调用析构函数。
默认构造函数是 不带参数的构造函数 或者 所有的参数均有默认值
1.有且只有一个 默认构造函数;
2.没有定义任何构造函数时,编译器会自动定义一个。被称为 合成默认构造函数。
使用 单个参数的构造函数 进行类类型转换 : 由 string类型 转换到 Data类型
一般 除非想要 定义隐式转换;否则应将 单个参数的构造函数 使用explicit修饰,避免错误。
用一个变量 初始化 另一个对象;
int a = b;
对于类而言,实现这个功能,就是 复制构造函数(一种特殊的构造函数)
用一个已经生成的类对象,初始化另一个同类的类对象。
1.形参 有且只有一个,且为本类类型的引用,且用const修饰;
2.对象的复制(该函数的功能,从无到有),与对象的赋值 (从有到新)是不同的概念;
3.如果没有 复制构造函数,编译器会自动生成一个,称为 合成复制构造函数;
使用复制初始化的函数 的三种情况
1.初始化
2.作为函数的形参或返回值进行 值传递时
3.对象数组 ={};初值列表的形式初始化。
【15min】
【注】:当类里面有 数据成员是指针的时候,就要考虑这个问题了!
浅复制 在delete的时候,有可能出现问题。(系统自动生成的复制构造函数,都是浅复制!所以有必要定义自己的 复制构造函数 以便实现深复制)
例子:
构造函数的重载:系统选择使用哪一个函数(同名函数)
带有默认参数的构造函数!(非常有效)
1.必须在类内指定默认参数;
2.【注意】:不要同时使用 构造函数的重载 和带默认参数的构造函数,以免发生歧义!(特例是,所有参数均有默认参数的构造函数 和 无参数构造函数)
初始化:在定义的同时,就为变量赋初值。
构造函数,就是用来 在创建对象时,为对象数据成员赋初始值的!
构造函数之所以存在,是因为在类定义时,数据成员是不能被初始化的;
public成员可以在外部赋初值,但是,private和protected是不能在外部访问的。
举个例子:
1.构造函数自动执行;
2.构造函数一般声明为public
3.构造函数一般只与初始化成员有关,但是可以包含任意语句(不提倡);
4.构造函数需要初始化所有成员;
5.构造函数的形参,是由定义对象时的实参给定的,要求 类型、个数、次序完全一样
初始化列表形式的构造函数
初始化列表的 length(l) <==> 函数体里的 length = l;
构造函数中,只能使用初始化列表完成初始化的特殊情况:
默认构造函数是指,没有参数的构造函数。
初始化列表的次序,是声明的次序。
类的实例化——对象; 内置类型的实例化——变量(对象);
此处的 对象 是狭义的概念,即,由类定义的实体。
和一般的使用基本一致。
同样是,new 和 delete
【注意】:此时得到的对象没有名字,我们使用 指向这个对象的指针 来访问这个对象。
delete p;//必须要 撤销,且和new 一一对应。
例子:
在定义类的时候,数据成员是public,所以可以直接用p->width直接使用。
对象成员 包括数据成员、成员函数;
且在 类外调用时,只能访问 public成员。
1. 对象名.成员名
Data A;
A.x = 1;
A.fun(4,5,6);
2.对象指针->成员
Data A, *p=&A;
p->x = 1;
p->fun(4,5,6);
3.对象的引用变量.成员名
Data A, &r=A;
A.x = 1;
A.fun(4,5,6);
同一个类的 多个对象之间可以 相互赋值;(对于 普通的数据成员而言)
函数的返回值 可以是对象、对象指针、对象引用
因此,局部变量一定要用 对象才可以返回。
【注意】:函数的类型,一个是 指向Data类型的指针,一个是Data类型的引用(就等同于Data类型)
若A中 嵌入了B的对象,则称A为子对象?
只能在类体里面使用
(::)作用域运算符,成员函数可以访问这个类的任何成员
【注】:习惯:成员函数的声明,放在类体里;成员函数的实现放在类外;除非成员函数本身很简单(四行或五行)。
C++会自动将类体内定义的 成员函数为inline函数。
成员函数可以重载,可以设定参数的默认值,且只能在类内部进行;
存储方式:(下面的 成员函数的存储空间是不合理的,只占有一段存储空间)
C++把成员函数的代码存储在对象空间之外的地方,且类的存储空间长度只取决于数据成员所占的空间,与成员函数无关。
前向类型:在声明之后,定义之前 是一个不完全的类型;
##25.1
面向过程:自顶向下,逐步求精;(制造一台电脑)
面向对象:实体;机器的世界 现实的世界;提高代码的可重用性;(组装一台电脑)
抽象
1.数据抽象(姓名、年龄)
2.行为抽象(上课、考试)
封装
使用者 不需要知道细节,只需要通过接口来使用
继承和派生
在原有基础类的基础上,
设计类、和使用类 两种程序员。
成员函数的定义有两种:
1.全部在类内定义;2.实现放在类外;
一般把类定义放在程序文件的开头,或者放在头文件中。
访问员,有两个:
1.类成员函数;2.类用户
类成员有访问控制属性:1.public;2.private(默认);3.protected(派生);