智能指针
c++11标准下的智能指针有两种:
- unique_ptr
- shared_ptr
使用智能指针
#include <memory>
std::unique_ptr<double> pdu(new double);
std::unique_ptr<std::string> pss(new std::string);
使用智能指针的时候,需要注意它的生命周期。
unique_ptr和shared_ptr的区别
unique_ptr使用的是所有权模型,也就是说一个对象只能被一个智能指针所拥有,赋值操作会剥夺之前智能指针的所有权。这种操作在 C++11 里面是不合法的。
int main()
{
std::string my_string("Hello World");
std::unique_ptr<std::string> pstr(new std::string(my_string));
std::unique_ptr<std::string> pstr2;
pstr2 = pstr; //编译报错
std::cout << *pstr;
return 0;
}
shared_ptr 使用的引用计数,只有当引用计数降低到0的时候,会调用析构函数。上面的代码如果换成shared_ptr,将能够正常运行。
智能指针的选择
unique_ptr 最大的特点就是不能够进行复制和赋值。如果程序不需要多个指向同一个对象的指针,那么可以直接使用 unique_ptr。
vector
vector类似string,是一种动态数组。可以在运行的阶段动态地创建数组,分配内存,也可以在末尾添加数据,在中间插入数据。
!使用vector需要包含标准头文件 #include <vector>
,vector类在名称空间 std
中。
vector
功能十分强大,但是其效率稍低。如果需要使用的是长度固定的数组,使用数组是更好的选择。
vector的声明和使用
#include <vector>
//声明 vector<typeName> vtName(n_elem);
std::vector<double> my_vec(10);
//声明 vector<typeName> vtName(n_elem, init_value);
std::vector<double> my_vec(5, 10);
//vector 类似指针,不检查越界,但是可以使用 at 方法防止越界
my_vec[-1]; // 不报错,但是很危险。相当于 *(my_vec-1)
my_vec.at(-1); // invalid syntax
需要引用 vector
库。定义vector对象的时候,需要指明其类型和数量,因为vector是动态创建的。
vector常用的方法:
v.push_back(1); //增加一个元素‘1’,长度增加1
v.emplace_back(element); // 末尾追加元素,c++11新特性,主要用于追加临时对象,减少复制构造。
vector<int>::iterator it; //新建一个迭代器it
v.begin(); //返回一个开始的迭代器
v.end(); // 返回一个超过容器尾的迭代器
for (p=v.begin(); p!=v.end(); p++){
...
} // 遍历整个vector
vec.insert(vec.begin()+i,a); //在第i+1个元素前面插入a;
vec.erase(vec.begin()+2); //删除第3个元素
vec.erase(vec.begin()+i,vec.end()+j); //删除区间[i,j-1];区间从0开始
vec.size(); //返回向量大小
vec.clear(); //清空该向量
vec.empty(); //该vector是否为空
emplace_back v.s. push_back
emplace_back
函数的作用是减少对象拷贝和构造次数,是C++11中的新特性,主要适用于对临时对象的赋值。
在使用push_back函数往容器中增加新元素时,必须要有一个该对象的实例才行,而emplace_back可以不用,它可以直接传入对象的构造函数参数直接进行构造,减少一次拷贝和赋值操作。
详细解释
array
- 长度固定,静态存储
- 需要
#include <array>
,在名称空间std
中。
array的声明和使用
#include <array>
//声明 array<typeName, n_elem> arName;
std::array<double, 5> my_array;
//不检查越界,可以使用成员函数at()
my_array.at(-2); // invalid syntax
数组,array, vector
- 数组复制的时候必须逐个元素赋值,但是array,vector都可以直接赋值。