3.3. Library vector Type3.3. 标准库 vector 类型A vector is a collection of objects of a single type, each of which has an associated integer index. As with strings, the library takes care of managing the memory associated with storing the elements. We speak of a vector as a container because it contains other objects. All of the objects in a container must have the same type. We'll have much more to say about containers in Chapter 9. vector 是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。和 string 对象一样,标准库将负责管理与存储元素相关的内存。我们把 vector 称为容器,是因为它可以包含其他对象。一个容器中的所有对象都必须是同一种类型的。我们将在第九章更详细地介绍容器。 To use a vector, we must include the appropriate header. In our examples, we also assume an appropriate using declaration is made: 使用 vector 之前,必须包含相应的头文件。本书给出的例子,都是假设已作了相应的 using 声明: #include <vector> using std::vector; A vector is a class template. Templates let us write a single class or function definition that can be used on a variety of types. Thus, we can define a vector that holds strings, or a vector to hold ints, or one to hold objects of our own class types, such as Sales_items. We'll see how to define our own class templates in Chapter 16. Fortunately, we need to know very little about how templates are defined in order to use them. vector 是一个类模板(class template)。使用模板可以编写一个类定义或函数定义,而用于多个不同的数据类型。因此,我们可以定义保存 string 对象的 vector,或保存 int 值的 vector,又或是保存自定义的类类型对象(如 Sales_items 对象)的 vector。将在第十六章介绍如何定义程序员自己的类模板。幸运的是,使用类模板时只需要简单了解类模板是如何定义的就可以了。 To declare objects of a type generated from a class template, we must supply additional information. The nature of this information depends on the template. In the case of vector, we must say what type of objects the vector will contain. We specify the type by putting it between a pair of angle brackets following the template's name: 声明从类模板产生的某种类型的对象,需要提供附加信息,信息的种类取决于模板。以 vector 为例,必须说明 vector 保存何种对象的类型,通过将类型放在类型放在类模板名称后面的尖括号中来指定类型: vector<int> ivec; // ivec holds objects of type int vector<Sales_item> Sales_vec; // holds Sales_items As in any variable definition, we specify a type and a list of one or more variables. In the first of these definitions, the type is vector<int>, which is a vector that holds objects of type int. The name of the variable is ivec. In the second, we define Sales_vec to hold Sales_item objects. 和其他变量定义一样,定义 vector 对象要指定类型和一个变量的列表。上面的第一个定义,类型是 vector<int>,该类型即是含有若干 int 类型对象的 vector,变量名为 ivec。第二个定义的变量名是 Sales_vec,它所保存的元素是 Sales_item 类型的对象。
3.3.1. Defining and Initializing vectors3.3.1. vector 对象的定义和初始化The vector class defines several constructors (Section 2.3.3, p. 49), which we use to define and initialize vector objects. The constructors are listed in Table 3.4. vector 类定义了好几种构造函数(2.3.3 节),用来定义和初始化 vector 对象。表 3.4 列出了这些构造函数。
Creating a Specified Number of Elements创建确定个数的元素When we create a vector that is not empty, we must supply value(s) to use to initialize the elements. When we copy one vector to another, each element in the new vector is initialized as a copy of the corresponding element in the original vector. The two vectors must hold the same element type: 若要创建非空的 vector 对象,必须给出初始化元素的值。当把一个 vector 对象复制到另一个 vector 对象时,新复制的 vector 中每一个元素都初始化为原 vectors 中相应元素的副本。但这两个 vector 对象必须保存同一种元素类型: vector<int> ivec1; // ivec1 holds objects of type int vector<int> ivec2(ivec1); // ok: copy elements of ivec1 into ivec2 vector<string> svec(ivec1); // error: svec holds strings, not ints We can initialize a vector from a count and an element value. The constructor uses the count to determine how many elements the vector should have and uses the value to specify the value each of those elements will have: 可以用元素个数和元素值对 vector 对象进行初始化。构造函数用元素个数来决定 vector 对象保存元素的个数,元素值指定每个元素的初始值: vector<int> ivec4(10, -1); // 10 elements, each initialized to -1 vector<string> svec(10, "hi!"); // 10 strings, each initialized to "hi!"
Value Initialization值初始化When we do not specify an element initializer, then the library creates a value initialized element initializer for us. This library-generated value is used to initialize each element in the container. The value of the element initializer depends on the type of the elements stored in the vector. 如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进行值初始化(value initializationd)。这个由库生成的初始值将用来初始化容器中的每个元素,具体值为何,取决于存储在 vector 中元素的数据类型。 If the vector holds elements of a built-in type, such as int, then the library creates an element initializer with a value of 0: 如果 vector 保存内置类型(如 int 类型)的元素,那么标准库将用 0 值创建元素初始化式:
vector<string> fvec(10); // 10 elements, each initialized to 0
If the vector holds elements of a class type, such as string, that defines its own constructors, then the library uses the value type's default constructor to create the element initializer: 如果 vector 保存的是含有构造函数的类类型(如 string)的元素,标准库将用该类型的默认构造函数创建元素初始化式:
vector<string> svec(10); // 10 elements, each an empty string
There is a third possibility: The element type might be of a class type that does not define any constructors. In this case, the library still creates a value-initialized object. It does so by value-initializing each member of that object. 还有第三种可能性:元素类型可能是没有定义任何构造函数的类类型。这种情况下,标准库仍产生一个带初始值的对象,这个对象的每个成员进行了值初始化。 3.3.2. Operations on vectors3.3.2. vector 对象的操作The vector library provides various operations, many of which are similar to operations on strings. Table 3.5 lists the most important vector operations. vector 标准库提供了许多类似于 string 对象的操作,表 3.5 列出了几种最重要的 vector 操作。
The size of a vectorvector 对象的 sizeThe empty and size operations are similar to the corresponding string operations (Section 3.2.3, p. 83). The size member returns a value of the size_type defined by the corresponding vector type. empty 和 size 操作类似于 string 的相关操作(3.2.3 节)。成员函数 size 返回相应 vector 类定义的 size_type 的值。
vector<int>::size_type // ok vector::size_type // error Adding Elements to a vector向 vector 添加元素Thepush_back operation takes an element value and adds that value as a new element at the back of a vector. In effect it "pushes" an element onto the "back" of the vector: push_back 操作接受一个元素值,并将它作为一个新的元素添加到 vector 对象的后面,也就是“插入(push)”到 vector 对象的“后面(back)”: // read words from the standard input and store them as elements in a vector string word; vector<string> text; // empty vector while (cin >> word) { text.push_back(word); // append word to text } This loop reads a sequence of strings from the standard input, appending them one at a time onto the back of the vector. We start by defining text as an initially empty vector. Each trip through the loop adds a new element to the vector and gives that element the value of whatever word was read from the input. When the loop completes, text will have as many elements as were read. 该循环从标准输入读取一系列 string 对象,逐一追加到 vector 对象的后面。首先定义一个空的 vector 对象 text。每循环一次就添加一个新元素到 vector 对象,并将从输入读取的 word 值赋予该元素。当循环结束时,text 就包含了所有读入的元素。 Subscripting a vectorvector 的下标操作Objects in the vector are not named. Instead, they can be accessed by their position in the vector. We can fetch an element using the subscript operator. Subscripting a vector is similar to subscripting a string (Section 3.2.3, p. 87). vector 中的对象是没有命名的,可以按 vector 中对象的位置来访问它们。通常使用下标操作符来获取元素。vector 的下标操作类似于 string 类型的下标操作(3.2.3 节)。. The vector subscript operator takes a value and returns the element at that position in the vector. Elements in a vector are numbered beginning with 0. The following example uses a for loop to reset each element in the vector to 0: vector 的下标操作符接受一个值,并返回 vector 中该对应位置的元素。vector 元素的位置从 0 开始。下例使用 for 循环把 vector 中的每个元素值都重置为 0: // reset the elements in the vector to zero for (vector<int>::size_type ix = 0; ix != ivec.size(); ++ix) ivec[ix] = 0; Like the string subscript operator, the vector subscript yields an lvalue so that we may write to it, which we do in the body of the loop. Also, as we do for strings, we use the size_type of the vector as the type for the subscript. 和 string 类型的下标操作符一样,vector 下标操作的结果为左值,因此可以像循环体中所做的那样实现写入。另外,和 string 对象的下标操作类似,这里用 size_type 类型作为 vector 下标的类型。
Subscripting Does Not Add Elements下标操作不添加元素Programmers new to C++ sometimes think that subscripting a vector adds elements; it does not: 初学 C++ 的程序员可能会认为 vector 的下标操作可以添加元素,其实不然: vector<int> ivec; // empty vector for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec[ix] = ix; // disaster: ivec has no elements
This code intended to insert new 10 elements into ivec, giving the elements the values from 0 through 9. However, ivec is an empty vector and subscripts can only be used to fetch existing elements. 上述程序试图在 ivec 中插入 10 个新元素,元素值依次为 0 到 9 的整数。但是,这里 ivec 是空的 vector 对象,而且下标只能用于获取已存在的元素。 The right way to write this loop would be 这个循环的正确写法应该是: for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec.push_back(ix); // ok: adds new element with value ix
![]() |