首页
外语
计算机
考研
公务员
职业资格
财经
工程
司法
医学
专升本
自考
实用职业技能
登录
计算机
下面是一个数组类的声明与实现。请分析这个类有什么问题,并针对存在的问题提出几种解决方案。 template class Array { public: Array(unsigned arraySize):data(0), size(arraySize)
下面是一个数组类的声明与实现。请分析这个类有什么问题,并针对存在的问题提出几种解决方案。 template class Array { public: Array(unsigned arraySize):data(0), size(arraySize)
admin
2019-03-29
102
问题
下面是一个数组类的声明与实现。请分析这个类有什么问题,并针对存在的问题提出几种解决方案。
template
class Array
{
public:
Array(unsigned arraySize):data(0), size(arraySize)
{
if(size > 0)
data = new T[size];
}
~Array()
{
if(data) delete[] data;
}
void setValue(unsigned index, const T& value)
{
if(index < size)
data[index] = value;
}
T getValue(unsigned index) const
{
if(index < size)
return data[index];
else
return T();
}
private:
T* data;
unsigned size;
};
选项
答案
public: Array(const Array& copy):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& operator = (const Array& copy) { 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)); } } 为了防止有多个指针指向的数据被多次删除,我们还可以保存究竟有多少个指针指向该数据。只有当没有任何指针指向该数据的时候才可以被删除。这种思路通常被称之为引用计数技术。在构造函数中,引用计数初始化为1;每当把这个实例赋值给其他实例或者以参数传给其他实例的构造拷贝函数的时候,引用计数加1,因为这意味着又多了一个实例指向它的data;每次需要调用析构函数或者需要把data赋值为其他数据的时候,引用计数要减1,因为这意味着指向它的data的指针少了一个。当引用计数减少到0的时候,data已经没有任何实例指向它了,这个时候就可以安全地删除。实现的代码如下: public: Array(unsigned arraySize) :data(0), size(arraySize), count(new unsigned int) { *count = 1; if(size > 0) data = new T[size]; } Array(const Array& copy) : size(copy.size), data(copy.data), count(copy.count) { ++ (*count); } ~Array() { Release(); } const Array& operator = (const Array& copy) { if(data == copy.data) return *this; Release(); data = copy.data; size = copy.size; count = copy.count; ++(*count); } private: void Release() { --(*count); if(*count == 0) { if(data) { delete []data; data = NULL; } delete count; count = 0; } } unsigned int *count;
解析
我们注意在类的内部封装了用来存储数组数据的指针。软件存在的大部分问题通常都可以归结指针的不正确处理。
这个类只提供了一个构造函数,而没有定义构造拷贝函数和重载拷贝运算符函数。当这个类的用户按照下面的方式声明并实例化该类的一个实例
Array A(10);
Array B(A);
或者按照下面的方式把该类的一个实例赋值给另外一个实例
Array A(10);
Array B(10);
B=A;
编译器将调用其自动生成的构造拷贝函数或者拷贝运算符的重载函数。在编译器生成的缺省的构造拷贝函数和拷贝运算符的重载函数,对指针实行的是按位拷贝,仅仅只是拷贝指针的地址,而不会拷贝指针的内容。因此在执行完前面的代码之后,A.data和B.data指向的同一地址。当A或者B中任意一个结束其生命周期调用析构函数时,会删除data。由于他们的data指向的是同一个地方,两个实例的data都被删除了。但另外一个实例并不知道它的data已经被删除了,当企图再次用它的data的时候,程序就会不可避免地崩溃。
由于问题出现的根源是调用了编译器生成的缺省构造拷贝函数和拷贝运算符的重载函数。一个最简单的办法就是禁止使用这两个函数。于是我们可以把这两个函数声明为私有函数,如果类的用户企图调用这两个函数,将不能通过编译。实现的代码如下:
private:
Array(const Array& copy);
const Array& operator = (const Array& copy);
最初的代码存在问题是因为不同实例的data指向的同一地址,删除一个实例的data会把另外一个实例的data也同时删除。因此我们还可以让构造拷贝函数或者拷贝运算符的重载函数拷贝的不只是地址,而是数据。由于我们重新存储了一份数据,这样一个实例删除的时候,对另外一个实例没有影响。这种思路我们称之为深度拷贝。
转载请注明原文地址:https://kaotiyun.com/show/qRmZ777K
0
程序员面试
相关试题推荐
Thecommitteehasanticipatedtheproblemsthat______intheroadconstructionproject.
Weakdollarorno,$46,000—thepriceforasingleyearofundergraduateinstructionamidtheredbrickofHarvardYard—is【C1】__
请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
将一整数逆序后放入一数组中(要求递归实现)
n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。
在Word97的编辑状态,执行“文件”菜单中的“保存”命令后()。A.将所有打开的文档存盘B.只能将当前文档存储在原文件夹的文件内C.可以将当前文档存储在已有的任意文件夹内D.可以先建立一个新文件夹,再将文档存储在该文件夹内
Powerpoint2000中,使用()菜单中的“幻灯片母版”命令,进入幻灯片母版设计窗口,更改幻灯片的母版。A.编辑B.工具C.视图D.格式
若程序内已定义了一个结构型数据:TYPERECORDCHARACTER(len=30)::name,addressINTEGER::Phone_numberENDTYPERECORD则以下类型为RECORD的数组说明语句中正确的是__
随着网络信息技术的进步和社会信息化程度的不断提高,一个由庞大的网络产业带动,并导致整个经济社会产生巨大变革的数字经济时代已经离我们越来越近。目前,“数字化校园”、“数字企业”、“数字城市”等一系列项目快速上马,在这些项目中,信息的数字化与数字信息的网络传输
在实际应用中,用户通常依靠评价程序来测试系统的性能。以下评价程序中,(16)的评测准确程度最低。事务处理性能委员会(TransactionProcessingPerformanceCouncil,TPC)是制定商务应用基准程序(Benchmark)标
随机试题
管理理论研究的先驱们通过实验研究,总结出“工人是社会人,而不是经济人”的观点。这个试验是()
心悸的发生多因( )
6-磷酸果酸激酶-1的最强别构激活剂是
关于特异感觉投射系统的描述,恰当的是
最易发生感染性休克和皮肤大片瘀斑的化脓性脑膜炎类型是
设备监理单位在设备监理活动中具有组织有关各方协作、配合的职能,同时是合同管理的主要承担者,具有调解有关各方之间权益矛盾、维护合同双方合法权益的职能。为使这些职能得以实施,设备监理单位必须坚持其( )。
某基金公司在其门户网站上发布新基金宣传材料,关于此新基金的宣传材料下列表述错误的是()。I.该材料事先经督察长检查,并出具合规意见书即可,无须再向当地中国证监会派出机构Ⅱ.该材料与基金合同、基金招募说明书相符,无须再向当地中国证监会派出
某企业年初从银行取得一笔贷款,期限为1年,年利率为10%,按照贴现法付息,已知贷款合同约定贷款到期时的还款额为100万元,则该笔贷款的本金为()万元。
甲企业为增值税一般纳税人。2008年企业有关业务资料如下:(1)1月20日,通过银行开出一张面值为468000元、期限3个月的不带息银行承兑汇票,用以采购一批材料。取得的增值税专用发票注明:不含税材料价款400000元,增值税额68000元。甲企业同时交
诗的源头是歌谣。上古时候,没有字,只有唱的歌谣。没有写的诗。一个人高兴的时候或悲哀的时候,常愿意将自己的心情诉说出来,给别人或自己听。日常的言语不够劲儿,便用歌唱,一唱三叹得叫别人回肠荡气。唱叹再不够的话,便手也舞起来了,脚也蹈起来了,反正要将劲儿使到了家
最新回复
(
0
)