class TestClass{
}
class SeqStack{
public:
SeqStack(int size = 10){
_pstack = new int[size];
_top = -1;
_size = size;
}
~SeqStack(){
delete []_pstack;
_pstack = nullptr;
}
private:
int *_pstack;
int _top;
int _size;
}
/*------------------------------------------------------------------------------------------------------------------------------*/
int main(){
TestClass s;//没写构造函数和析构函数,会调用系统生成的空构造函数和空析构函数
SeqStack s1(30);
SeqStack s2(s1);//拷贝构造函数,与下面这句意义相同
SeqStack s3 = s1;//没写拷贝构造函数,会生成默认的拷贝构造函数
/*对象默认的拷贝构造是做内存的数据拷贝,直接将s1内存中保存的三个成员变量的值给s3(即所谓的浅拷贝),这样s1和s3的_qstack指向了同一块堆内存,当s3先析构时
delete []_pstack,将此块堆内存释放,s1的_pstack便成为了野指针,轮到s1析构就会报错*/
s3 = s1;/*对象赋值操作,默认的赋值函数做的也是内存拷贝(浅拷贝),同样会在第二次析构出错。不仅让两个指针指向一块外部资源,在s3完成深拷贝的情况下还让s3把 指向的外部资源直接丢了*/
}
浅拷贝出错的情况:对象中有成员变量指针指向了对象内存之外的外部的资源,在第二个对象析构时出错
所以需要自己写一个深拷贝构造函数
SeqStack(const SeqStack &src){
_pstack = new int[src._size];//为新类单独开辟外部资源
for(i=0;i<=src._top;++i){
_pstack[i] = src._pstack[i];
}
_top = src._top;
_size = src._size;
}
Q:为什么需要用for循环做深拷贝,而不是memcpy
如果拷贝的两个数组中存的是对象,那就不能单纯的进行内存拷贝了
//赋值重载函数
void operator=(const SeqStack &src){
if(this == &src){
return;//防止自赋值
}
delete[]_pstack;//将当前对象占用外部资源释放
//以下与拷贝构造相同
_pstack = new int[src._size];
for(i=0;i<=src._top;++i){
_pstack[i] = src._pstack[i];
}
_top = src._top;
_size = src._size;
}