type
status
slug
summary
tags
category
password
date
icon
Buzzwords
- encapsulation 封装
- inheritance 继承
- polymorphism 多态
- overriding 覆盖
- interface 接口、界面
- cohesion 内聚
- coupling 耦合
- collection classes 容器
- template 模版
- responsibility-driven design 责任驱动
c++ improvements
Data abstraction
Access control
Initialization & cleanup
References
Function overloading
Streams for I/O
Name control
Operator overloading
More safe and powerful memory management
Templates
Exception handling
Format output
Manipulators are special functions that can be included in the I/O statement to alter.
the format parameters of a stream.
endl is one of the manipulators.
Create a string & alter string
search string
container
What is STL
STL = Standard Template Library
Part of the ISO Standard C++ Library
Data Structures and algorithms for C++
拷贝赋值运算符
假如我们有两个
container
的实例,那么如果两个实例相等,会发生什么事情?那么可以很清楚的发现,这两个容器现在指向同一块内存了
值得注意的是,这样的赋值实际上本质上是一种共享,并非真正的建立了一个副本
这个例子演示了一个重载
operaor=
的例子,将from中指向的内容拷贝了一份,而非简单的拷贝指针值是一样的,深拷贝的概念
c++中允许我们进行重新定义 重载赋值运算符
导致原来的val中的东西都没有了
进行防止自我拷贝的处理:
c++允许我们使用operator 进行运算符重载
结合函数重载,我们也容易理解,
operator=
同样可以有重载。例如:运算符重载
既然
operator=
可以重载,那么其他运算符可不可以重载呢?答案是肯定的。C++ 希望表达方式是灵活且自由的;对于自定义类型,C++ 希望人们能写出 F = M * A
,而非 assign(F, mul(M, A))
。事实上,C 语言的运算符就在一定程度上做了「重载」。回顾上一节的定义,重载的含义是同一个函数(根据参数列表不同)具有不同的行为。例如,
*
运算符作为单目运算符时是取值运算符,而作为双目运算符时表示相乘;+
运算符在两个算术类型之间表示求和,而对于 ptr + i
时其实表示 ptr + i * sizeof(A)
,其中 ptr
的类型是 A*
。而 C++ 允许用户重载大多数的运算符从而提高代码的简洁性和可维护性。
考虑一个存放
M * M
大小矩阵的类 Matrix
:int中没有运算符built-in的重载
此时,如果我们写
m1 * m2
,其实就等价于 m1.operator*(m2)
,就调用我们写的重载了!这样的实现方式确实能够实现上述操作,但是它限制了我们只能写出
Matrix * int
而不能写出 int * Matrix
,因为后者被解释为 int::operator*(Matrix)
,但是 int
中并没有这样的重载(C++ 也不希望支持给内部类型增加新的运算2)如何解决这个问题呢?事实上,运算符重载也可以放在全局,例如:
如何解决这个问题呢?事实上,C++ 允许一个类的定义中给一个外部的函数3「授予」访问其 private 成员的权限,方式是将对应的函数在该类的定义中将对应的函数声明为一个 友元 (friend):
注意:
友元只是一种权限授予的声明,友元函数并非类的成员。因此它并不受 access-specifier 的影响。
当然,还可以这样进行解决:
其他大多数运算符也能重载。对于一元运算符(如作为正负号的
+
, -
,以及 !
, ~
, ++
, --
等),@x
会调用 x.operator@()
或者 operator@(x)
。如 -x
会调用 x.operator-()
或者 operator-(x)
。STL
STL包括算法,容器,迭代器
容器和算法都可以使用迭代器进行无缝的连接
几乎所有的代码都使用了模版类和模版函数的方式
使用STL的好处:
- STL是C++中的一部分
- STL是数据结构和算法的分离
STL中的vector容器中,可以放入元素,技术数据类型变量,元素地址
- 不需要思考STL具体实现的过程,只需要熟练使用STL就可以了
- STL具有高可重用性,高性能,高移植性,跨平台的特点
- 跨平台
- 高移植性
- 模版类和模版函数的方式
- 高性能,例如map可以高效的进行查询检索,使用红黑树的变体进行实现
- 红黑树是平衡二叉树的一种
容器的分类:
- 序列形容器
- 取决于插入时机和地点
- 和元素值无关
- 每个元素都有固定的位置
vector
deque
list
queue
- 关联式容器
- 和插入顺序无关
- 取决于特定的排序准则
set
multiset
map
multimap
vector
vector是C++标准模板库(STL)中一个非常重要和常用的序列容器。它是一种动态数组,可以在常数时间内随机访问元素。
尾部添加和删除元素比较容易但是中间比较费时
下面是vector的一些主要用法:
- 构造函数:
vector<int> v;
//创建空vectorvector<int> v(10);
//创建初始大小为10的vectorvector<int> v(10, 1);
//创建初始大小为10且值全为1的vectorvector<int> v1(v2);
//用v2创建v1vector<int> v(arr, arr+5);
//从数组arr中前5个元素创建vector
- 元素访问:
v[i];
//访问第i个元素v.front();
//访问首元素v.back();
//访问尾元素
- 迭代器:
v.begin();
//返回首元素迭代器v.end();
//返回尾端的迭代器v.rbegin();
//返回最后元素的反向迭代器v.rend();
//返回首元素的反向迭代器
- 容量:
v.size();
//返回实际元素个数v.capacity();
//返回总容量v.resize(n);
//改变实际元素个数为nv.reserve(n);
//将总容量预留为n
- 修改:
v.push_back(x);
//在尾部添加一个xv.pop_back();
//删除尾元素v.insert(it, x);
//在迭代器it处插入xv.erase(it);
//删除迭代器it所指元素v.clear();
//清空所有元素
- 其他:
v1 = v2;
//直接赋值拷贝v1 == v2;
//判断两vector相等sort(v.begin(), v.end());
//对vector排序
vector支持随机访问,能高效地访问和修改任意位置元素。但在中间插入或删除元素时,需要移动后续元素,因此效率较低。它在尾部插入和删除效率很高。当事先知道存储数据量的上限时,可以通过reserve来减少vector的内存重新分配次数。
deque
deque是C++标准模板库(STL)中的一个容器适配器,它提供了一种双端队列的实现。deque可以高效地在头部和尾部进行插入和删除操作,与vector相比,deque在中间进行插入和删除操作的效率较低。
使用deque的主要优点包括:
- 双端访问: 可以高效地在两端进行插入和删除操作。
- 空间高效利用: 与vector相比,deque通常会分散在不同的内存块中,更好地利用内存。
- 内存利用灵活: 当内存不足时,deque会分配新的内存块,因此不需要像vector那样一次性地申请大量内存。
下面是一些常用的deque操作:
- 构造函数:
deque<int> deq;
// 默认构造一个空dequedeque<int> deq(10);
// 构造一个初始大小为10的dequedeque<int> deq(10, 1);
// 构造一个初始大小为10且初始值为1的deque
- 访问元素:
deq.front();
// 访问第一个元素deq.back();
// 访问最后一个元素deq[i];
// 访问第i个元素
- 插入元素:
deq.push_front(x);
// 在前端插入元素xdeq.push_back(x);
// 在尾部插入元素x
- 删除元素:
deq.pop_front();
// 删除第一个元素deq.pop_back();
// 删除最后一个元素
- 其他操作:
deq.size();
// 获取元素个数deq.empty();
// 判断是否为空deq.clear();
// 清空所有元素
deque常用于需要高效进行头尾插入删除的场景,如实现一个双端队列或栈。它也可以作为一般容器使用,但中间插入删除操作效率较低。
- 作者:fufu酱
- 链接:https://csfufu.life/article/73b7126b-52be-408c-8fb4-07b773549701
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。