12-3 怎样获取容器的元素
我们从 Container中取出对象时,应该得到类型T还是类型T&的对象呢?
更具决定意义的观点是:如果取出一个对象可以获得一个引用,就可以更容易地对还在容器中的对象进行修改。实际上,如果能够修改容器中的对象对我们来说很重要的话,那么容器要必须提供对象的引用。
获取引用的容器必须十分留意其所包含的对象的位置变化。
12-4 怎样区分读和写
完全可以用c[i]从容器c中取出下标为I的元素,而用c.update(i,x)将这个元素的值修改为x。
Container< Cotainer >c;
Index i, j;
int k = c[i][j];
//我们怎样才能更新c[i][j]???
可以尝试重载update来解决问题
void update(Index, const T&);
void update(Index, Index, const T&);
但是更高维的怎么办?
c[i].update(j, new_value);
// c[i] 返回类型T, 而不是T&
// 所以,当我们对c[i]调用update时,我们更改的是第i个Container
// 的第i个Container的一个临时副本。一旦复制完成,这个副本就会被丢弃
看起来最好的折中办法就是允许c[I]获得引用,并且提醒用户只能在创建之后才能使用它们。
12-5 怎样处理容器的增长
容器都需要某种方法将元素放入其中。区分向容器添加一个新元素的操作和改变一个已有元素的值的操作是很有用的。如果我们要存储一个 已不存在的元素,将会发生什么事情?取出一个这样的元素又会怎样?
设计有逐步扩展能力的容器时,该怎么考虑如何为容器中的元素分配内存?1:把容器中的所有内容都复制到刚能够容纳新旧内容的新的内存空间, 2:按区块增加容器的大小。
12-6 容器支持哪些操作
允许容器包含容器是否有用? 除非容器有一个缺省构造函数, 否则不可能创建一个容器数组。
应该如何顺序地遍历容器中的所有元素。
12-7 怎样设想容器元素的类型
如果有操作符符合我们所需的操作语义,则应该重载操作符。
容器最少应该需要复制,赋值, 和销毁类型为T的对象等操作。
判断两个元素是否相等的能力
输入输出操作。
12-8 容器和继承
数组和继承不可以混合使用。不同类型的容器不应该存在继承关系。
12-9 设计一个类似数组的类
搞清楚数组和指针之间的关系很重要。
int i;
for(i = 0; i < N; i++)
f(x[i])
T*p;
for(p=x; p
f(*p);
T* p = &x;
while(p < x+N)
f(*p++);
在下标的例子中,下标本身就有意义,而与它是否用做下标无关。
在指针的例子中,要访问容器的元素,没有必要知道容器的标识
指针自身就包含了必要的信息。
template calss Array {
public:
Array():data(0),sz(0) {}
Array(unsigned size):
sz(size), data(new T[size]) {}
~Array() { delete [] data; }
const T& operator[](unsigned n) const
{
if(n >= sz || data == 0)
throw "Array subscript out of range";
return data[n];
}
T& operator[] (unsigned n)
{
if(n >= sz || data == 0)
throe "Array subscript out of range";
return data[n];
}
operator const T*() const
{
return data;
}
operator T*()
{
return data;
}
private:
T* data;
unsigned sz;
Array(const Array& a);
Array& operator = (const Array&);
};
在类似数组的类中使用指针会带来一个缺陷:改变这样的类的实现或者增加它的操作都会突然使指向它的元素的指针失效。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/409557/viewspace-892602/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/409557/viewspace-892602/