C++ 标准库 工具库 线程库 容器库 时间库

本文深入探讨C++标准库核心组件,包括标准库函数、智能指针、容器、线程库、时间库等关键特性。解析vector、list、map等容器内部机制,详解unique_ptr与shared_ptr的使用技巧,及条件变量、互斥量等同步机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标准库

  • 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);

自定义容器

  1. 容器方法begin,end,size
  2. begin和end返回迭代器
  3. 迭代器操作符operator!=  operator++  operator*
  4. 迭代器能定位

时间库

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++通用工具

cppreference中文参考网站

cplusplus参考网站

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值