首页
外语
计算机
考研
公务员
职业资格
财经
工程
司法
医学
专升本
自考
实用职业技能
登录
计算机
下面是一个数组类的声明与实现。请分析这个类有什么问题,并针对存在的问题提出几种解决方案。 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
129
问题
下面是一个数组类的声明与实现。请分析这个类有什么问题,并针对存在的问题提出几种解决方案。
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
程序员面试
相关试题推荐
TheUnitedStatesInterstateHighwaySystemisaninfrastructurefeatofunprecedentedproportions.Notonlydoesitjoinallfi
Directions:Inthissection,youareaskedtowriteanessaybasedonthefollowinginformation.Makecommentsandexpressy
邮件的删除。
在控制面板中,将鼠标的"右手习惯"改为"左手习惯"。
计算机能直接识别和执行的语言是()A.机器语言B.高级语言C.数据库语言D.汇编程序
在Excel2003中,利用“图表选项”对话框,可以设置或修改图标的()。
企业战略数据模型可分为两种类型:(35)描述日常事务处理中的数据及其关系;(36)描述企业管理决策者所需信息及其关系。35
在数据库系统中,“事务”是访问数据库并可能更新各种数据项的一个程序执行单元。为了保证数据完整性,要求数据库系统维护事务的原子性、一致性、隔离性和持久性。针对事务的这4种特性,考虑以下的架构设计场景:假设在某一个时刻只有一个活动的事务,为了保证事务
若系统中存在n个等待事务Ti(i=0,1,2,…,n-1),其中:T0正等待被T1锁住的数据项A1,T1正等待被T2锁住的数据项A2,…,Ti正等待被Ti+1锁住的数据项Ai+1,…,Tn-1正等待被T0锁住的数据项A0,则系统处于___________状
随机试题
学校作为整个社会体系的重要组成部分,在培养国家和民族的未来人才中具有重要的作用。根据各级各类学校任务确定的对所培养的人的特殊要求叫作()。
Infootball,nothingismorevaluablethanthewonderkid.Managersspendplentyoftheirtimesearchingfortheseraregems(室石)
如果
用于治疗热毒疮疡,咽喉肿痛,药食中毒的药物是
以下哪条不是促进扩散的特征
一、背景某机电安装公司承建一个生活小区室外热力管网工程安装任务。施工范围是由市政热力管网至各居民住宅楼号室外1m,管线是不通行地沟敷设。该项目的所有施工内容完毕,并与市政热力管网和各楼号热力管网接通后,在进行竣工验收的同时,项目经理部组织整理竣工
苏联早期领导人布哈林曾说:“我们过去以为可以一举消灭市场关系.而实际情况却表明,我们恰恰要通过市场关系走向社会主义。”这一思想符合苏俄(联)实行的经济政策是()。
当事人对于买卖合同风险转移没有约定的,标的物毁损、灭失的风险的转移时间是()。
设f(x),g(x)在[a,b]上连续,在(a,b)内可导,证明:存在ξ∈(a,b),使得
HowAdvertisementIsDone?A)Whenwechooseawordwedomorethangiveinformation;wealsoexpressourfeelingsaboutwha
最新回复
(
0
)