没有合适的资源?快使用搜索试试~ 我知道了~
首页The C++ Standard Library A Tutorial and Reference (2nd Edition)
The C++ Standard Library A Tutorial and Reference (2nd Edition)
1星 需积分: 9 11 下载量 106 浏览量
更新于2023-05-25
评论
收藏 7.54MB PDF 举报
C++ STL 最专业参考文档之一The C++ Standard Library A Tutorial and Reference (2nd Edition);英文版!
资源详情
资源评论
资源推荐
ptg7913098
7.3 Ve c t o r s 271
Ve c t o r s provide the usual size operations size(), empty(), and max_size() (see Section 7.1.2,
page 254). An additional “size” operation is the capacity() function, which returns the number of
elements a vector could contain in its actual memory. If you exceed the capacity(), the vector has
to reallocate its internal memory.
The capacity of a vector is important for two reasons:
1. Reallocation invalidates all references, pointers, and iterators for elements of the vector.
2. Reallocation takes time.
Thus, if a program manages pointers, references, or iterators into a vector , or if speed is a goal, it is
important to take the capacity into account.
To avoid reallocation, you can use reserve() to ensure a certain capacity before you really need
it. In this way , you can ensure that references remain valid as long as the capacity is not exceeded:
std::vector<int> v; // create an empty vector
v.reserve(80); // reserve memory for 80 elements
Another way to avoid reallocation is to initialize a vector with enough elements by passing additional
arguments to the constructor. For example, if you pass a numeric value as parameter, it is taken as
the starting size of the vector:
std::vector<T> v(5); // creates a vector and initializes it with five values
// (calls five times the default constructor of type T)
Of course, the type of the elements must provide a default constructor for this ability. For fundamen-
tal types, zero initialization (see Section 3.2.1, page 37) is guaranteed. But note that for complex
types, even if a default constructor is provided, the initialization takes time. If the only reason for
initialization is to reserve memory, you should use reserve().
The concept of capacity for vectors is similar to that for strings (see Section 13.2.5, page 669),
with one big difference: Unlike for strings, it is not possible to call reserve() for vectors to shrink
the capacity. Calling reserve() with an argument that is less than the current capacity is a no-op.
Furthermore, how to reach an optimal performance regarding speed and memory use is implementa-
tion defined. Thus, implementations might increase capacity in larger steps. In fact, to avoid internal
fragmentation, many implementations allocate a whole block of memory (such as 2K) the first time
you insert anything if you don’t call reserve() first yourself. This can waste a lot of memory if
you have many vectors with only a few small elements.
Because the capacity of vectors never shrinks, it is guaranteed that references, pointers, and
iterators remain valid even when elements are deleted, provided that they refer to a position before
the manipulated elements. However, insertions invalidate all references, pointers, and iterators when
the capacity gets exceeded.
C++11 introduced a new member function for vectors: a nonbinding request to shrink the capac-
ity to fit the current number of elements:
v.shrink_to_fit(); // request to shrink memory (since C++11)
This request is nonbinding to allow latitude for implementation-specific optimizations. Thus, you
cannot expect that afterward v.capacity==v.size() yields true.
Before C++11, there you could shrink the capacity only indirectly: Swapping the contents with
another vector swaps the capacity. The following function shrinks the capacity while preserving the
elements:
将vector所有元素拷贝到新的内存空间
ptg7913098
272 Chapter 7: STL Containers
template <typename T>
void shrinkCapacity(std::vector<T>& v)
{
std::vector<T> tmp(v); // copy elements into a new vector
v.swap(tmp); // swap internal vector data
}
You could even shrink the capacity without calling this function by calling the following statement:
5
// shrink capacity of vector v for type T
std::vector<T>(v).swap(v);
However, note that after swap(), all references, pointers, and iterators swap their containers. They
still refer to the elements to which they referred on entry. Thus, shrinkCapacity() invalidates all
references, pointers, and iterators. The same is true for shrink_to_fit().
Operation Effect
vector<Elem> c Default constructor; creates an empty vector without any
elements
vector<Elem> c(c2)
Copy constructor; creates a new vector as a copy of c2 (all
elements are copied)
vector<Elem> c = c2
Copy constructor; creates a new vector as a copy of c2 (all
elements are copied)
vector<Elem> c(rv)
Move constructor; creates a new vector , taking the contents
of the rvalue rv (since C++11)
vector<Elem> c = rv
Move constructor; creates a new vector , taking the contents
of the rvalue rv (since C++11)
vector<Elem> c(n)
Creates a vector with n elements created by the default
constructor
vector<Elem> c(n,elem) Creates a vector initialized with n copies of element elem
vector<Elem> c(beg,end) Creates a vector initialized with the elements of the range
[beg,end)
vector<Elem> c(initlist)
Creates a vector initialized with the elements of initializer
list initlist (since C++11)
vector<Elem> c = initlist Creates a vector initialized with the elements of initializer
list initlist (since C++11)
c.~vector()
Destroys all elements and frees the memory
Table 7.9. Constructors and Destructor of Ve c tor s
5
You (or your compiler) might consider this statement as being incorrect because it calls a nonconstant member
function for a temporary value. However, standard C++ allows you to call a nonconstant member function for
temporary values.
ptg7913098
7.3 Ve c t o r s 273
7.3.2 Vect o r Operations
Create, Copy, and Destroy
Table 7.9 lists the constructors and destructors for vectors. You can create vectors with and without
elements for initialization. If you pass only the size, the elements are created with their default
constructor. Note that an explicit call of the default constructor also initializes fundamental types,
such as int, with zero (see Section 3.2.1, page 37). See Section 7.1.2, page 254, for some remarks
about possible initialization sources.
Nonmodifying Operations
Table 7.10 lists all nonmodifying operations of vectors.
6
See additional remarks in Section 7.1.2,
page 254, and Section 7.3.1, page 270.
Operation Effect
c.empty() Returns whether the container is empty (equivalent to size()==0 but
might be faster)
c.size()
Returns the current number of elements
c.max_size()
Returns the maximum number of elements possible
c.capacity()
Returns the maximum possible number of elements without
reallocation
c.reserve(num)
Enlarges capacity, if not enough yet
6
c.shrink_to_fit() Request to reduce capacity to fit number of elements (since C++11)
6
c1 == c2 Returns whether c1 is equal to c2 (calls == for the elements)
c1 != c2
Returns whether c1 is not equal to c2 (equivalent to !(c1==c2))
c1 < c2
Returns whether c1 is less than c2
c1 > c2
Returns whether c1 is greater than c2 (equivalent to c2<c1)
c1 <= c2
Returns whether c1 is less than or equal to c2 (equivalent to
!(c2<c1))
c1 >= c2
Returns whether c1 is greater than or equal to c2 (equivalent to
!(c1<c2))
Table 7.10. Nonmodifying Operations of Ve cto r s
Assignments
Table 7.11 lists the ways to assign new elements while removing all ordinary elements. The set of
assign() functions matches the set of constructors. Yo u can use different sources for assignments
6
reserve() and shrink_to_fit() manipulate the vector because they invalidate references, pointers, and
iterators to elements. However, they are mentioned here because they do not manipulate the logical contents of
the container.
ptg7913098
274 Chapter 7: STL Containers
Operation Effect
c = c2 Assigns all elements of c2 to c
c = rv
Move assigns all elements of the rvalue rv to c (since C++11)
c = initlist
Assigns all elements of the initializer list initlist to c (since
C++11)
c.assign(n,elem)
Assigns n copies of element elem
c.assign(beg,end)
Assigns the elements of the range [beg,end)
c.assign(initlist)
Assigns all the elements of the initializer list initlist
c1.swap(c2)
Swaps the data of c1 and c2
swap(c1,c2)
Swaps the data of c1 and c2
Table 7.11. Assignment Operations of Vect o r s
(containers, arrays, standard input) similar to those described for constructors (see Section 7.1.2,
page 254). All assignment operations call the default const ructo r, copy constructor, assignment
operator, and/or destructor of the element type, depending on how the number of elements changes.
For example:
std::list<Elem> l;
std::vector<Elem> coll;
...
// make coll be a copy of the contents of l
coll.assign(l.begin(),l.end());
Element Access
To access all elements of a vector , you must use range-based for loops (see Section 3.1.4, page 17),
specific operations, or iterators. Table 7.12 shows all vector operations for direct element access. As
usual in C and C++, the first element has index 0, and the last element has index size()-1. Thus,
the nth element has index n-1. For nonconstant vectors, these operations return a reference to the
element. Thus, you could modify an element by using one of these operations, provided it is not
forbidden for other reasons.
Operation Effect
c[idx] Returns the element with index idx (no range checking)
c.at(idx)
Returns the element with index idx (throws range-error exception
if idx is out of range)
c.front()
Returns the first element (no check whether a first element exists)
c.back()
Returns the last element (no check whether a last element exists)
Table 7.12. Direct Element Access of Ve c tor s
The most important issue for the caller is whether these operations perform range checking.
Only at() performs range checking. If the index is out of range, at() throws an out_of_range
ptg7913098
7.3 Ve c t o r s 275
exception (see Section 4.3, page 41). All other functions do not check. A range error results in
undefined behavior. Calling operator [ ], front(), and back() for an empty container always
results in undefined behavior:
std::vector<Elem> coll; // empty!
coll[5] = elem; // RUNTIME ERROR ⇒ undefined behavior
std::cout << coll.front(); // RUNTIME ERROR ⇒ undefined behavior
So, you must ensure that the index for operator [ ] is valid and that the container is not empty when
either front() or back() is called:
std::vector<Elem> coll; // empty!
if (coll.size() > 5) {
coll[5] = elem; // OK
}
if (!coll.empty()) {
cout << coll.front(); // OK
}
coll.at(5) = elem; // throws out_of_range exception
Note that this code is OK only in single-threaded environments. In multithreaded contexts, you need
synchronization mechanisms to ensure that coll is not modified between the chec k for its size and
the access to the element (see Section 18.4.3, page 984, for details).
Iterator Functions
Ve c t o r s provide the usual operations to get iterators (Table 7.13). Vector iterators are random-access
iterators (see Section 9.2, page 433, for a discussion of iterator categories). Thus, in principle you
could use all algorithms of the STL.
The exact type of these iterators is implementation defined. For vectors, however, the iterators
returned by begin(), cbegin(), end(), and cend() are often ordinary pointers, which is fine
because vectors usually use a C-style array for the elements and ordinary pointers provide the inter-
face of random-access iterators. However, you can’t count on the fact that the iterators are ordinary
pointers. For example, if a safe version of the STL that checks range errors and other potential prob-
lems is used, the iterator type is usually an auxiliary class. See Section 9.2.6, page 440, for a nasty
difference between iterators implemen ted as pointers and iterators implemented as classes.
Iterators remain valid until an element with a smaller index gets inserted or removed or until
reallocation occurs and capacity changes (see Section 7.3.1, page 270).
Inserting and Removing Elements
Table 7.14 shows the operations provided for vectors to insert or to remove elements. As usual when
using the STL, you must ensure that the arguments are valid. Iterators must refer to valid positions,
and the beginning of a range must have a position that is not behind the end.
剩余1189页未读,继续阅读
xuhaoee
- 粉丝: 0
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- zigbee-cluster-library-specification
- JSBSim Reference Manual
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论1