若不提供构造函数和析构函数,则编译器会提供。编译器提供的构造函数和析构函数是空实现。
构造函数:
用于在创建对象时为对象的成员属性赋值,构造函数由编译器自行调用且只会调用一次。
构造函数没有返回值,函数名称与类的名称相同,可以有参数因而可以函数重载。
1.c++编译器会给一个类添加三个构造函数:无参/默认构造函数、有参构造函数、拷贝构造函数。若用户提供了有参构造函数则c++将不会提供无参构造函数,但仍会提供拷贝构造函数,如果需要用到默认构造函数,用户可以自行添加默认构造函数;若用户提供了拷贝构造函数,则编译器将不再提供默认构造函数和有参构造函数,若用户需要用到这两个构造函数可以自行编写添加。
2.调用拷贝构造函数的时机:
使用一个已经创建完毕的对象来初始化一个新的对象;
以值传递的方式给函数参数传值(传对象);
以值的方式返回局部对象。
3.拷贝构造函数的定义中需要将被拷贝的对象以引用(多是常量引用)的方式传参,若是传值则是先会构造一个副本,这个过程又会涉及到构造函数的调用,会递归不终止。
4.构造函数还可以使用初始化列表的形式进行初始化:
foo(string s, int i) : name(s), id(i){ }
函数体内可以是空实现,当一个类中包含另一个类的情况下,假设id是属于一个类ID,那么这种初始化方式可以对类内类进行初始化相当于 ID id = i;即为隐式转换法来创建该类的一个对象加入到其所属类中。
析构函数:
在对象销毁前由编译器自行调用且仅调用一次进行清理工作。
没有返回值,函数名前加上波浪号,名称同类名称,它不可以有参数因而不可以发生重载。
深拷贝和浅拷贝:
1.浅拷贝只会拷贝一层,是简单的赋值操作,也是编译器调用默认拷贝构造函数时(用户未指定拷贝构造函数)使用的方式。
2.深拷贝将拷贝过程中遇到的所有引用类型都开辟一块地址拷贝对应的数据。
当某属性用到了堆区(new分配的用指针接收的空间)空间时,若在析构函数中进行释放堆区空间的操作时)由于浅拷贝是对引用的拷贝(仅仅将接收指针进行了拷贝),因而在执行析构函数时,会对同一片堆区空间进行重复的释放(两次释放空间使用的指针其实一样)。