标题: 让人头痛的Vector(思索篇)
- FantasySoft 2004-08-08 00:13 阅读:993
- 评论:2 查看评论 | 添加评论

        在让人头痛的Vector(提问篇)给大家留了一个问题,hyifeng老大说对了,如果使用vec[0] = 0这种方式的话,"The vector is empty!"是会被打印出来的。然而使用push_back(0),则不会打印出来。
        这是为什么呢?首先,empty()函数的值就是布尔表达式vec.size() == 0的返回值,既然"The vector is empty!"被打印出来,那么就意味着size()的返回值为0了,于是就继续去看size()函数的实现:   

[图片]size_type size() const
[图片][图片][图片]{
[图片]   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的初始值?接着我查看了"[]" 运算符重载的源代码:

[图片]const_reference operator[](size_type _P) const
[图片][图片][图片]{
[图片]  return (*(begin() + _P)); 
[图片]}

        然而在push_back()函数的实现当中,则是调用了insert函数:

[图片]void push_back(const _Ty& _X)
[图片][图片][图片]{
[图片]  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()则会改变,因此就会产生篇首所说的结果了。


查看评论 | 添加评论
返回顶部 | 返回首页