智能指针

c++11标准下的智能指针有两种:

  • unique_ptr
  • shared_ptr

使用智能指针

  1. #include <memory>
  2. std::unique_ptr<double> pdu(new double);
  3. std::unique_ptr<std::string> pss(new std::string);

使用智能指针的时候,需要注意它的生命周期。

unique_ptr和shared_ptr的区别

unique_ptr使用的是所有权模型,也就是说一个对象只能被一个智能指针所拥有,赋值操作会剥夺之前智能指针的所有权。这种操作在 C++11 里面是不合法的。

  1. int main()
  2. {
  3. std::string my_string("Hello World");
  4. std::unique_ptr<std::string> pstr(new std::string(my_string));
  5. std::unique_ptr<std::string> pstr2;
  6. pstr2 = pstr; //编译报错
  7. std::cout << *pstr;
  8. return 0;
  9. }

shared_ptr 使用的引用计数,只有当引用计数降低到0的时候,会调用析构函数。上面的代码如果换成shared_ptr,将能够正常运行。

智能指针的选择

unique_ptr 最大的特点就是不能够进行复制和赋值。如果程序不需要多个指向同一个对象的指针,那么可以直接使用 unique_ptr。

vector

vector类似string,是一种动态数组。可以在运行的阶段动态地创建数组,分配内存,也可以在末尾添加数据,在中间插入数据。

!使用vector需要包含标准头文件 #include <vector>,vector类在名称空间 std 中。

vector 功能十分强大,但是其效率稍低。如果需要使用的是长度固定的数组,使用数组是更好的选择。

vector的声明和使用

  1. #include <vector>
  2. //声明 vector<typeName> vtName(n_elem);
  3. std::vector<double> my_vec(10);
  4. //声明 vector<typeName> vtName(n_elem, init_value);
  5. std::vector<double> my_vec(5, 10);
  6. //vector 类似指针,不检查越界,但是可以使用 at 方法防止越界
  7. my_vec[-1]; // 不报错,但是很危险。相当于 *(my_vec-1)
  8. my_vec.at(-1); // invalid syntax

需要引用 vector 库。定义vector对象的时候,需要指明其类型和数量,因为vector是动态创建的。

vector常用的方法:

  1. v.push_back(1); //增加一个元素‘1’,长度增加1
  2. v.emplace_back(element); // 末尾追加元素,c++11新特性,主要用于追加临时对象,减少复制构造。
  3. vector<int>::iterator it; //新建一个迭代器it
  4. v.begin(); //返回一个开始的迭代器
  5. v.end(); // 返回一个超过容器尾的迭代器
  6. for (p=v.begin(); p!=v.end(); p++){
  7. ...
  8. } // 遍历整个vector
  9. vec.insert(vec.begin()+i,a); //在第i+1个元素前面插入a;
  10. vec.erase(vec.begin()+2); //删除第3个元素
  11. vec.erase(vec.begin()+i,vec.end()+j); //删除区间[i,j-1];区间从0开始
  12. vec.size(); //返回向量大小
  13. vec.clear(); //清空该向量
  14. vec.empty(); //该vector是否为空

emplace_back v.s. push_back

emplace_back函数的作用是减少对象拷贝和构造次数,是C++11中的新特性,主要适用于对临时对象的赋值。
在使用push_back函数往容器中增加新元素时,必须要有一个该对象的实例才行,而emplace_back可以不用,它可以直接传入对象的构造函数参数直接进行构造,减少一次拷贝和赋值操作。
详细解释

array

  • 长度固定,静态存储
  • 需要 #include <array>,在名称空间 std 中。

array的声明和使用

  1. #include <array>
  2. //声明 array<typeName, n_elem> arName;
  3. std::array<double, 5> my_array;
  4. //不检查越界,可以使用成员函数at()
  5. my_array.at(-2); // invalid syntax

数组,array, vector

  • 数组复制的时候必须逐个元素赋值,但是array,vector都可以直接赋值。