对象的初始化和清理
●构造函数:没有返回值 没有void,类名相同,可以发生重载,可以有参数
●析构函数:没有返回,没有void ,函数名称: ~类名,不可以发生重载,不可以有参数
●系统如何调用:
系统会默认调用 构造函数和析构函数,而且只会调用一次
如果程序员没有提供构造和析构,系统会默认提供,空实现
构造函数的分类及调用
●按照参数分类
无参构造(默认构造) 有参构造
●按照类型分类
普通构造函数 拷贝构造函数
●无参构造写法 和调用
Person p1 ; 注意不能写 Person p1() ,因为编译器认为这个是函数声明
●有参构造写法 和调用
Person p2(10) 或者 Person p2 = Person(10)
Person(10) 匿名对象 ,执行当前行后就会释放这个对象
●拷贝构造函数
Person( const Person & p ) 记得加&
Perons p1( p2) 或者 Person p1 = Person(p2)
不能用拷贝构造函数初始化匿名对象
如果写成 Person (p1) 这种写法等价于 Person p1
写到右值可以做拷贝构造函数
● Person P = 100隐式类型转换 相当于调用 Person p = Person(100)
拷贝构造函数调用时机
release默认会做优化
●用已经创建好的对象来初始化新的对象
●以值传递的方式给函数参数传值
●以值方式返回局部对象
前两种调用拷贝构造
系统生成构造函数规则
●如果提供了有参的构造,那么系统就不会提供默认的构造了,但是会提供拷贝构造
●如果提供了拷贝构造函数,那么系统就不会提供其他的(构造和拷贝)构造函数了
深拷贝与浅拷贝
原因:系统默认提供的拷贝构造 会进行简单的值拷贝,如果属性里有指向堆区空间的数据,那么简单的浅拷贝会导致析构函数重复释放内存的异常
解决:需要我们自己提供拷贝构造函数,动态分配内存,进行深拷贝
初始化列表语法
在构造函数后面 + : 属性(值、参数), 属性(值、参数)…
类对象作为成员时构造函数的调用
当类对象作为类的成员时候,构造顺序是先构造类对象的构造,然后构造自己,,析构顺序与构造相反
explicit关键字
防止构造函数中的隐式类型转换
new和delete
●使用:Person * p = new Person
会返回一个Person指针
●注意:
new默认调用构造函数
new出来的数组,肯定会调用默认构造函数,而栈区分配的可以调用其他构造函数
new 对象用void* 去接受,释放不了对象
返回不是void* ,不需要强制转换
delete [] 告诉编译器是对象数组
●malloc的不足: