让人头痛的Vector(思索篇)
2004-08-08 00:13 FantasySoft 阅读(2035) 评论(1) 编辑 收藏 举报 在让人头痛的Vector(提问篇)给大家留了一个问题,hyifeng老大说对了,如果使用vec[0] = 0这种方式的话,"The vector is empty!"是会被打印出来的。然而使用push_back(0),则不会打印出来。
这是为什么呢?首先,empty()函数的值就是布尔表达式vec.size() == 0的返回值,既然"The vector is empty!"被打印出来,那么就意味着size()的返回值为0了,于是就继续去看size()函数的实现:
{
return (_First == 0 ? 0 : _Last - _First);
}
在这里要说明一下:在Vector类当中,定义了三个Iterator:_Last、_First和_End。因为size()返回值为0,那么我们可以想到_Last = _First。而事实上当程序执行reserve()为Vector分配了内存之后,我们可以通过调用begin()和end()函数可以验证_Last 与 _First的初始值是相等。
难道vec[0] = 0这样的符值方式并不会改变_Last的初始值?接着我查看了"[]" 运算符重载的源代码:
{
return (*(begin() + _P));
}
然而在push_back()函数的实现当中,则是调用了insert函数:
{
insert(end(), _X);
}
iterator insert(iterator _P, const _Ty& _X = _Ty())
{
size_type _O = _P - begin();
insert(_P, 1, _X);
return (begin() + _O);
}
void insert(iterator _P, size_type _M, const _Ty& _X)
{
if(_End - _Last < _M)
{
size_type _N = size() + (_M < size() ? size() : _M);
iterator _S = allocator.allocate(_N, (void *)0);
iterator _Q = _Ucopy(_First, _P, _S);
_Ufill(_Q, _M, _X);
_Ucopy(_P, _Last, _Q + _M);
_Destroy(_First, _Last);
allocator.deallocate(_First, _End - _First);
_End = _S + _N;
_Last = _S + size() + _M;
_First = _S;
}
else if (_Last - _P < _M)
{
_Ucopy(_P, _Last, _P + _M);
_Ufill(_Last, _M - (_Last - _P), _X);
fill(_P, _Last, _X);
_Last += _M;
}
else if (0 < _M)
{
_Ucopy(_Last - _M, _Last, _Last);
copy_backward(_P, _Last - _M, _Last);
fill(_P, _P + _M, _X);
_Last += _M;
}
}
由这些代码我们就可以得知,直接通过"[]"操作符去对Vector中element去赋值是不会改变_Last这个iterator的值(事实上如果使用''[]"操作符就会改变_Last的话也是没有意义的),而push_back()则会改变,因此就会产生篇首所说的结果了。