【100题】含有指针成员的类的拷贝问题~~

来源:互联网 发布:xls文件解密软件 编辑:程序博客网 时间:2024/06/04 08:22
template<typename T>class Array{private:T *data;unsigned int size;public ://带参数的构造函数Array(unsigned int arraySize):data(0),size(arraySize){if(size > 0){data = new T[size];}}//析构函数~Array(){if(data != NULL){delete[] data;}}//设置下标为index的值void setValue(unsigned int index,const T &value){if(index < size){data[index] = value;}}//返回下标为index的值T getValue(unsigned int index) const{if(index < size){return data[index];}else{return T();}}};

 

注意这个程序有个成员变量是指针类型


这个程序有问题:

先看两种情况

(1)Array A(10);

(2)Array B(A); 这里需要调用拷贝构造函数

(3)Array C(20);

(4)C = A; 这里需要调用赋值运算符

但是该类的定义中没有显示定义,但没关系,系统会默认提供这两个成员函数。

编译器生成的缺省的拷贝构造函数和赋值操作符,对于指针实行的是浅拷贝,就是按位拷贝,仅仅只是拷贝指针的地址,而不会拷贝指针所指向的内容。

所以在(2)(4)执行完之后,A.data和B.data指向的同样内存地址。当A或B析构时,会删除data,也就是删除了两次!!造成系统崩溃!如下图所示

 

 解决办法:

方法1,禁用复制和赋值操作!即把拷贝构造函数和赋值操作符声明为私有的,这样的话,(2)(4)的两种写法是编译不通过的!

#include <iostream>using namespace std;//template<typename T>class Array{private:T *data;unsigned int size;private:Array(const Array ©);const Array &operator = (const Array ©);public ://带参数的构造函数Array(unsigned int arraySize):data(0),size(arraySize){if(size > 0){data = new T[size];}}//析构函数~Array(){if(data != NULL){delete[] data;}}//设置下标为index的值void setValue(unsigned int index,const T &value){if(index < size){data[index] = value;}}//返回下标为index的值T getValue(unsigned int index) const{if(index < size){return data[index];}else{return T();}}};//测试用例void main(){Array<int> A(10);/*情况一*///Array<int> B(A);//情况二Array<int> B(10);B = A;}


1>------ 已启动全部重新生成: 项目: 2012.7.2, 配置: Debug Win32 ------
1>正在删除项目“2012.7.2”(配置“Debug|Win32”)的中间文件和输出文件
1>正在编译...
1>1.cpp
1>c:\users\user\desktop\一日一练\2012.7.2\2012.7.2\1.cpp(59) : error C2248: “Array<T>::operator =”: 无法访问 private 成员(在“Array<T>”类中声明)
1>        with
1>        [
1>            T=int
1>        ]
1>        c:\users\user\desktop\一日一练\2012.7.2\2012.7.2\1.cpp(12) : 参见“Array<T>::operator =”的声明
1>        with
1>        [
1>            T=int
1>        ]
1>生成日志保存在“file://c:\Users\user\Desktop\一日一练\2012.7.2\2012.7.2\Debug\BuildLog.htm”
1>2012.7.2 - 1 个错误,0 个警告
========== 全部重新生成: 成功 0 个,失败 1 个,跳过 0 个 ==========

编译说不能访问私有函数,禁用了~

方法2,自定义重载这两个函数,实现深拷贝~~

#include <iostream>using namespace std;//template<typename T>class Array{private:T *data;unsigned int size;public ://带参数的构造函数Array(unsigned int arraySize):data(0),size(arraySize){if(size > 0){data = new T[size];}}//析构函数~Array(){if(data != NULL){delete[] data;}}//拷贝构造函数Array(const Array ©):data(0),size(copy.size){if(size > 0){data = new T[size];for(int i=0; i<size; ++i){setValue(i,copy.getValue(i));}}}//赋值操作符const Array<int> &operator = (const Array<int> ©){if(this == ©){return *this;}if(data != NULL){delete[] data;data = NULL;}size = copy.size;if(size > 0){data = new T[size];for(int i=0; i<size; ++i){setValue(i,copy.getValue(i));}}}//设置下标为index的值void setValue(unsigned int index,const T &value){if(index < size){data[index] = value;}}//返回下标为index的值T getValue(unsigned int index) const{if(index < size){return data[index];}else{return T();}}};//测试用例void main(){Array<int> A(10);/*情况一*///Array<int> B(A);//情况二Array<int> B(10);B = A;}


 

方法3:引用计数

#include <iostream>using namespace std;//template<typename T>class Array{private:T *data;unsigned int size;unsigned int *count;void Release(){--(*count);if(*count == 0){if(data){delete []data;data = NULL;}delete count;count = 0;}}public ://带参数的构造函数Array(unsigned int arraySize):data(0),size(arraySize),count(new unsigned int){*count=1;if(size > 0){data = new T[size];}}//析构函数~Array(){Release();}//拷贝构造函数Array(const Array ©):data(copy.data),size(copy.size),count(copy.count){++(*count);}//赋值操作符const Array<int> &operator = (const Array<int> ©){if(this == ©){return *this;}Release();data = copy.data;size = copy.size;count = copy.count;++(*count);}//设置下标为index的值void setValue(unsigned int index,const T &value){if(index < size){data[index] = value;}}//返回下标为index的值T getValue(unsigned int index) const{if(index < size){return data[index];}else{return T();}}};//测试用例void main(){Array<int> A(10);/*情况一*///Array<int> B(A);//情况二Array<int> B(10);B = A;}


 

 

 

 

 

 

 

 

 

原创粉丝点击