第十三章:访问容器中的元素1
12章中Array和指针之间的密切关系付出代价:即使Array本身不存在了,指针仍然在那里;另外不得不保露类内部机制。
本章设计:将成功的保留指针的表达能力,同时有能避免这些不足。
13-1 模拟指针
C++的设计原则就是用类来表示概念。指针把数组的标识和内部空间结合在一起。
template class Pointer {
private:
Array* ap;
unsigned sub;
//...
};
我们知道Pointer要在Array中封装一个指针,和在Array中的位置;
现在必须决定要允许Pointer 对象进行哪些操作。
考虑构造函数,析构函数,复制和赋值是设计类的一个很好的起点。
对于构造函数,要求两个参数都有似乎比较合理,这样可以彻底消除越界 Pointer(不一定把?如果给的数值比较大,指下标)。
template class Pointer {
public:
Pointer(Array& a, unsigned n = 0);
ap(&a), sub(n) {} // 为什么n为0
Pointer():ap(0),sub(0) {}
//....
private:
Array* ap;
unsigned sub;
};
13-2 获取数据
template class Pointer {
public:
T& operator*() const {
if(ap == 0)
throw "Of unbound Pointer";
return (*ap)[sub];
}
//...
};
麻烦在于:这种定义得到一个引用。这个引用指向隐藏在响应的Array中的数据结构中的一个元素(引用是什么,一个地址,而return返回却是一个元素的值,不明白?)。这将意味着实现细节将再次暴露给用户(更不明白?)。
template class Pointer {
public:
T operator*() const {
if(ap == 0)
throw "Of unbound Pointer";
return (*ap)[sub]; //这句话本身就是返回一个值,
//而不是引用呀?
}
//...
};
改动一下,带来新问题?所做的工作就是让operator*返回一个T,而不是T&.(为什么?),所以我们不能对它赋值。换句话说,如果p是一个Pointer,这种改变回允许
t = *p; //是元素
但会禁止 *P =t; //不明白,做实验验证一下。
关键在于,如果允许
p = t; //(*ap)[sub] =t ;怎么禁止了?
也就很难禁止
T* tp = &*p; //获得地址
而上面这种用法正是我们想要禁止的。
不能简单的禁止使用Pointer来更新Array相应的元素。该怎么办?
引入叫update的操作。
不用*p=t;
而用p.update(t);
template class Pointer {
public:
Pointer(Array& a, unsigned n = 0):
ap(&a), sub(n) {}
Pointer():ap(0), sub(0) {}
T operator*() const {
if(ap == 0)
throw "* of unbound Pointer";
return (*ap)[sub];
}
void update(const T& t) {
if (ap == 0)
thorw "update of unbound Pointer";
(*ap)[sub] = t;
}
//...
private:
Array* ap;
unsigned sub;
};
使用update带来的问题?
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/409557/viewspace-893321/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/409557/viewspace-893321/