explicit 可以用于构造函数 禁止隐式转化
class One
{
public:
explicit One(int a)
{
num = a;
}
private:
int num;
};
int main()
{
One test(11);
One www = 1; //这里会出错 不允许从int 转为 One 若是去掉1explicit就没问题
}
unique_ptr 因为只有一个 所以 它的删除器放在 智能指针里边
std::unique_ptr<int, std::function<void(int*)>> ptr(new int(10),
[](int* p) {
std::cout << "自定义删除器:释放内存 " << *p << std::endl;
delete p; // 手动删除指针
}
std::shared_ptr<int> ptr(new int(20),
[](int* p) {
std::cout << "自定义删除器:释放内存 " << *p << std::endl;
delete p; // 手动删除指针
}
);
智能指针不是线程安全的 它读安全 写不安全
atomic原子操作 在多线程比锁要高效 没有上下文的切换
自旋锁 就是互斥锁其中的锁轮询 不休眠
STLArray
如同C语言中数组 它是一个聚合体
初始化
它是STL中唯一一个 没有指定初始值的时候会被预初始化的容器
在基础类型的初始化中 可能会给它不确定的值
它不能用()来进行初始化 用{}来初始化后若里边没有元素都初始化为0
Array操作
支持随机访问 可以使用STL中所有算法
内部方法 fill (xxx) 给Array中内部元素都赋值为xxx
元素访问
有四个方法
at [] front back 后边两个是返回第一个和最后一个元素
这四个当中只有at 有异常检测 若是不满足就会抛出out_of_range的异常 后面三个若是异常就会有不明确行为 所以推荐用at来访问元素
Vector
理解为动态数组
大小与容量
Vector的容量非常重要 它与大小有关的函数有 size(),empty(),max_size() capacity(),
其中 capacity返回的是Vector的容量 若是加入的元素后超过这个容量 那么就会扩容 ( 这扩容好像是1.5倍还是2倍) 但是扩容操作是非常费时间的 一旦内存重新分配,vector元素相关的所有reference、pointer、iterator 都会失效。
可以使用reserve()保留适当容量,避免重新分配内存。如此一来,只要保留的容量尚有富余,就不必担心reference 失效。
std::vector<int> v;
vectorv.reserve(80);//reserve memory for 80 elements
避免重新分配内存的另一个方法是,初始化期间就向构造函数传递额外实参,构建足够的空间。如果你的实参是个数值,它将成为vector的起始大小。std::vector<T>y(5);
这必须 T具有默认的构造函数
还有 reserve 传入的数如果比实际的容量要小就没效果
有一个比较有技巧的方法来缩小vector的容量
template <typename T>
void shrinkCapacity(std::vector<T>&v)
{
std::vector<T> tmp(v);
v.swap(tmp);//copy elements into a new vector//swap internal vector data
}
//还有一个更牛的
v.swap(v); //但是经过测试 这样好像不行容量没变
c++11推出了shrink_to_fit 这个方法 它减少容器的容量以适应其大小并销毁超出容量的所有元素。
Vector的操作
赋值 比较注意的就是
c.assign(n,elem)复制n个elem,赋值给c
c.assign(beg,end)将区间[beg,end)内的元素赋值给c
c.assign(initlist)将初值列inizlist的所有元素赋值给c
元素访问
与上边相同 at [] front back
这四个当中只有at 有异常检测 若是不满足就会抛出out_of_range 其他的不做检查
Deque
除了头插和尾插入 在其他任何地方插入元素都会使得reference、pointer、iterator 都会失效
由于其内部结构它不用在内存复制所有元素
它不提供容量操作
List
类似于带头结点的双向链表