标准库
- std::system 调用运行环境命令处理器
- std::getenv 获取环境变量
- std::exit
- std::atof
- std::rand
工具库
类型支持
- std::size_t
- std::nullptr_t 字面量nullptr的类型
- std::type_info 类型信息typeid(int)
- std::is_integral
- std::rank 数组维度
动态内存管理
指针类别
unique_ptr
// 初始化
unique_ptr<int> p(new int(2));
unique_ptr<int> p = std::move(p);
// 修改器
release
reset
swap
// 其他
get
get_deleter
operator*
operator->
operator bool
shared_ptr (初始化、修改器、删除器 + 智能指针)
// 将普通指针复制给共享对象智能指针编译会出错
// nullptr可以直接复制,所以不要将普通指针直接复制给共享对象智能指针
// 初始化两种方式
std::shared_ptr<int> p(new int(2));
std::shared_ptr<int> p = make_shared<int>(2);
// 修改管理指针
reset
swap
// 最常用
get
use_count
operator*
operator->
operator bool
// 指定删除器
std::shared_ptr<int> p(new int, [](int* p){delete p;});
std::shared_ptr<int> p(new int[10], [](int* p){delete []p;});
std::shared_ptr<int> p(new int[10], std::default_delete<int[]>);
// 注意点
// 1. 不要用原始指针初始化多个shared_ptr
// 2. 不要在函数实参中创建shared_ptr
// 3. 不要直接返回shared_ptr<T>(this),而是继承enable_shared_from_this,返回shared_from_this()
// 4. 不要循环引用
// 共享指针的继承关系转换
std::dynamic_pointer_cast
std::shared_ptr<baseclass> ptrbase;
std::shared_ptr<derivedclass> ptrderived = std::dynamic_pointer_cast<derivedclass>(ptrbase);
weak_ptr
// 常用的三个方法
operator= 进 赋值shared_ptr
expired 判断shared_ptr是否释放资源
lock 出 返回shared_ptr
// 类似shared_ptr
reset
swap
use_count
分配器
allocator
1.分配空间(allocate)
2.构造(construct)
3.析构(destroy)
4.释放空间(deallocate)
#include <iostream>
#include <memory>
using namespace std;
int main(int argc, char* argv[])
{
allocator<string> alloc;
int n = 10;
string* p = alloc.allocate(n);
string* q = p;
while(q != p+n)
{
alloc.construct(q++, 10, 'w');
cout << *(q-1) << endl;
}
while(q != p)
{
alloc.destroy(--q);
}
alloc.deallocate(p, n);
return 0;
}
pair
tuple
直接构造和利用make_tuple来构造,std::tie用来将多个变量绑在一起或解绑,绑定得到是左值引用,解绑就是解构,可以用std::ignore来占位,不必解构每个值,tuple_cat用来连接pair和tuple
#include <iostream>
#include <string>
#include <tuple>
int main(int argc, char** argv)
{
unsigned int iNum = 1;
unsigned int iAge = 18;
std::string szName = "fang";
std::tuple<unsigned int, unsigned int, std::string> tuple0(iNum, iAge, szName);
std::tuple<unsigned int, unsigned int, std::string> tuple1 = make_tuple(iNum, iAge, szName);
std::tuple<unsigned int&, unsigned int&, std::string&> tuple2 = std::tie(iNum, iAge, szName);
//std::tuple<unsigned int&&, unsigned int&&, std::string&&>
//tuple3 = std::forward_as_tuple(iNum, iAge, szName);
std::string& szNameTmp1 = std::get<2>(tuple2);
szNameTmp1 = "zhao";
std::tuple<unsigned int, unsigned int, std::string, std::string>
au1 = std::tuple_cat(tuple1, std::tie(std::string("123")));
auto au2 = std::tuple_cat(tuple1, std::make_tuple(std::string("123")));
std::string& szNameTmp2 = std::get<3>(au1);
unsigned int iNumTmp = 0;
unsigned int iAgeTmp = 0;
std::string szNameTmp = "";
std::tie(std::ignore, iAgeTmp, szNameTmp) = tuple2;
return 0;
}
hash
例子
// hash example
#include <iostream>
#include <functional>
#include <string>
int main ()
{
char nts1[] = "Test";
char nts2[] = "Test";
std::string str1 (nts1);
std::string str2 (nts2);
std::hash<char*> ptr_hash;
std::hash<std::string> str_hash;
std::cout << "same hashes:\n" << std::boolalpha;
std::cout << "nts1 and nts2: " << (ptr_hash(nts1)==ptr_hash(nts2)) << '\n';
std::cout << "str1 and str2: " << (str_hash(str1)==str_hash(str2)) << '\n';
return 0;
}
/*
same hashes:
nts1 and nts2: false
str1 and str2: true
*/
其实就是得到一个std::size_t类型的哈希值,hash模板指定类型可参看http://www.cplusplus.com/reference/functional/hash/?kw=hash
hash模板T如需定义类型,hash<SSS> 需定义操作符operator(),同时可能自定义类型须定义operator==操作符
struct SSS {
string str1;
string str2;
};
/*
bool operator==(const SSS& lhs, const SSS& rhs) {
return lhs.str1 == rhs.str1 && lhs.str2 == rhs.str2;
}
*/
template<>
struct std::hash<SSS>
{
std::size_t operator()(const SSS& s) const
{
std::size_t hash1 = std::hash<string>{}(s.str1);
std::size_t hash2 = std::hash<string>{}(s.str2);
return hash1 ^ (hash2 << 1);
}
};
initlizer_list
{}
聚合类型类
- 没有自定义构造函数
- 无私有和保护的非静态数据成员
- 无基类
- 无虚函数
- 没有初始化
线程库
启动异步执行体
// 创建线程
std::thread thread1 = std::thread(<全局函数名>, args);
std::thread thread2 = std::thread(<类静态函数名>, this); // 不加&也有效
std::thread thread3 = std::thread(<类名::函数名>, this); // 加&
// 退出 - 通过参数控制函数执行结束
if (thread1.joinable())
{
thread1.join();
}
// 异步执行
std::future<int> result = std::async([this]() -> int { return classfunction(); });
if (result.valid())
{
result.wait();
result.get();
}
互斥量和条件变量
/* 等待1s */
#include <thread>
#include <chrono>
std::this_thread::sleep_for(std::chrono::seconds(1));
/* 条件等待和通知 */
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cov;
std::condition_variable_any cva;
// 条件等待 阻塞过程解锁 唤醒过程加锁
std::lock_guard<std::mutex> locker(mtx);
cva.wait(mtx);
std::unique_lock<std::mutex> locker(mtx);
cov.wait(locker);
// 通知条件 - 随机唤醒一个条件变量 - 唤醒所有条件变量
cva.notify_one();
cva.notify_all();
promise和future
#include <future>
std::promise<int> prom;
// 流程一 - 只能设置一次
prom.set_value (10);
// 流程二 - 获取future,然后get
std::future<int> sRetCodeFuture = prom.get_future();
if (sRetCodeFuture.valid()) { sRetCodeFuture.get(); }
容器库
顺序容器
实现能按顺序访问的数据结构
- vector
- list 双向链表
- deque
- array 静态数组 c++11
- forward_list 单向链表 c++11
vector array deque 都保留有连续内存,所有存取比较快
deque另外维护首地址,占用内存较多
list支持高效插入删除操作
关联容器
有序关联容器 - 实现能快速查找( O(log n) 复杂度)的数据结构
- set
- map
- multiset
- multimap
无序关联容器 - 提供能快速查找(均摊 O(1) ,最坏情况 O(n) 的复杂度)的无序(哈希)数据结构
- unordered_set
- unordered_map
- unordered_multiset
- unordered_multimap
容器适配器
容器适配器提供顺序容器的不同接口
- stack 默认底层容器deque,支持vector、deque、list
- queue 默认底层容器deque,支持deque、list
- priority_queue 默认底层容器vector,支持vector、deque
其他容器
initlizer_list - 在构造函数中使用该容器,可以用初始化列表
string
//1.将字符串s1转换为大写
transform(s1.begin(),s1.end(),s1.begin(),toupper);
//2.将字符串s1转化为小写
transform(s1.begin(),s1.end(),s1.begin(),tolower);
自定义容器
- 容器方法begin,end,size
- begin和end返回迭代器
- 迭代器操作符operator!= operator++ operator*
- 迭代器能定位
时间库
c时间库<ctime>或者<time.h>
std::clock_t std::clock()
- time_t 时间类型
- time 纪元起时间
- localtime 纪元起时间到日历时间
c++时间库<chrono>
duration时间间隔 - nanoseconds microseconds milliseconds seconds minutes hours
- count计次的计数
- duration_cast转换时长到另一个拥有不同嘀嗒间隔的时长
time_point时间点
转换为time_t使用
clocks时钟
system_clock
- now 返回当前time_point
- to_time_t 转换系统时钟时间点time_t为 std::time_t
- from_time_t 转换 std::time_t 到系统时钟时间点time_t
steady_clock 暂无
high_resolution_clock 暂无
- std::chrono::high_resolution_clock::now()
#include <chrono>
// 计算时间间隔
// 1.
std::chrono::time_point<std::chrono::system_clock> start_;
std::chrono::time_point<std::chrono::system_clock> end_;
start_ = std::chrono::system_clock::now();
end_ = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed = end_ - start_;
std::chrono::duration<double, std::milli> elapsed = end_ - start_;
std::chrono::duration<double, std::micro> elapsed = end_ - start_;
elapsed.count();
// 2.
std::clock_t start_ = std::chrono::system_clock::now();
std::clock_t end_ = std::chrono::system_clock::now();
(end_ - start_)/CLOCKS_PER_SEC;
// 3.
auto start_= std::chrono::high_resolution_clock::now();
auto end_ = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli>(end_-start_).count();
// time_t与time_point互转(既c和c++时间点互转)
std::chrono::time_point<std::chrono::system_clock> cc_t;
std::time_t c_t = std::time(nullptr);
cc_t = std::chrono::system_clock::from_time_t(c_t);
c_t = std::chrono::system_clock::to_time_t(cc_t);
// time_t to tm
std::time_t c_t = std::time(nullptr);
std::tm* c_tm = std::localtime(&c_t);
其他库
#include <locale> // std::wstring_convert
#include <codecvt> // std::codecvt_utf8
std::string wstringToUtf8(const std::wstring& wstr)
{
std::wstring_convert<std::codecvt_utf8<wchar_t> > strCnv;
return strCnv.to_bytes(wstr);
}
std::wstring utf8ToWstring(const std::string& str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t> > strCnv;
return strCnv.from_bytes(str);
}
参考
类似参考 c++标准库-c++通用工具