class date
{
public:
int year;
int month;
int day;
class stack
{
public:
int* a;
int top;
int capacity;
当我们为这两个类写其的拷贝构造函数用的是传值调用的情况下:
日期类是没有问题,因为编译器会为内置类型拷贝遍历创建临时变量
而栈类中top和capacity都是内置类型没有问题,主要是a这个变量,a是一个指向开辟在堆区的数组
假设st1和st2都是由st这个对象通过拷贝构造函数(传值调用)拷贝出来的,拷贝的时候会连指向空间的那个指针一起拷贝出来,也就是拷贝出来会变成st1和st2两个变量的a都指向同一块空间,这样会造成很严重的错误(进栈和free的时候)
注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请
时,则拷贝构造函数是一定要写的,否则就是浅拷贝。
在C++中,函数调用如果是传值调用都是需要创建一个临时变量,将值拷贝一份给这个临时变量,而将值拷贝一份本身就是一个拷贝构造函数,因此就会死循环,造成无穷递归。
若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
浅拷贝就是编译器自己会完成的,就一个内置类型按字节大小拷贝变量
字节序拷贝会如果变量是一个指向开辟在堆区的数组的指针,拷贝的不只有那个数组,还有其中的数据和指向这个数组的指针
注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定
义类型是调用其拷贝构造函数完成拷贝的。
编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?当然像日期类这样的类是没必要的。那么下面的类呢?验证一下试试?
我们最好在参数加个const修饰,这样可以防止权限放大