thread_local的作用
thread_local修饰的变量,可以理解为每个线程独有的静态变量 thread_local 的作用thread_local 是 C++11 引入的一个关键字,它用于声明线程局部存储(TLS)。线程局部存储指的是每个线程都有自己的变量副本,而这些副本在不同线程之间互不干扰。每个线程访问 thread_local 变量时,都会得到该变量的独立副本。 作用thread_local 的主要作用是确保每个线程都有该变量的独立副本,避免不同线程之间对该变量的竞争和冲突。这在多线程程序中非常重要,特别是当不同线程需要独立的状态或数据时。 如何使用 thread_localthread_local 可以修饰普通的变量、静态变量、类成员变量等。 语法:1thread_local type variable_name; 例如: 1thread_local int counter = 0; // 每个线程都有自己的独立 counter 变量 示例1. 基本用法12345678910111213141516171819202122#include...
explicit关键字
explicit 关键字在 C++ 中,explicit 是一个用于构造函数的修饰符,其主要作用是 防止隐式类型转换,从而避免某些情况下的代码歧义或意外错误。 用法 修饰构造函数,防止隐式类型转换。 修饰带有单个参数的构造函数,避免单参数的构造函数被用作隐式类型转换运算符。 语法1234class ClassName {public: explicit ClassName(Type param);}; 为什么需要 explicit? 默认情况下,C++ 会允许单参数构造函数被隐式调用,用于进行类型转换。这种行为有时会导致意外的错误。 使用 explicit 可以禁止这样的隐式转换。 示例1. 没有使用 explicit123456789101112131415161718192021#include <iostream>class MyClass {public: // 单参数构造函数 MyClass(int value) : m_value(value) {} void...
懒加载
懒加载(Lazy Initialization 或 Lazy Loading)是一种设计模式或编程技巧,它的核心思想是:延迟初始化资源,只有在真正需要的时候才创建或加载这些资源。 懒加载的特点 避免不必要的开销 如果资源加载非常耗时或占用大量内存,懒加载可以减少程序启动时的资源占用。 提升性能 只有在资源被真正需要时才加载,减少了程序的启动时间。 按需加载 资源是否加载取决于程序运行时的实际需求,可能避免加载某些资源。 懒加载的使用场景 单例模式 在单例模式中,实例对象通常会在第一次访问时才创建。 例如,你的 Logger 类的实现:1234Logger &Logger::instance() { static Logger logger; // 静态变量只在第一次调用时初始化 return logger;} Logger 对象只有在调用 Logger::instance()...
仿函数
在 C++ 中,仿函数(Function Object 或 Functor) 是一种行为类似于函数的对象。仿函数是通过重载 operator() 运算符来实现的,这样一个对象就可以像函数一样调用。 仿函数的核心思想是:对象可以具有类似函数的行为,并且可以携带状态。这为设计灵活的函数调用方式提供了可能性,尤其是在 STL(标准模板库)中,仿函数被广泛应用于算法、容器操作等场景。 1. 仿函数的基本概念仿函数是通过在一个类中重载 operator() 运算符来实现的。这样,类的对象就可以被调用(表现得像一个函数)。 仿函数的基本语法12345678910111213141516#include <iostream>using namespace std;class MyFunctor {public: // 重载 operator() void operator()(int x) { cout << "Called with: " << x << endl; ...
可调用对象的绑定器和包装器
在 C++ 中,可调用对象的绑定器和包装器是用来简化或增强对函数(包括普通函数、成员函数、函数对象、Lambda 表达式等)的调用操作的工具。它们广泛用于泛型编程和 STL 算法中,以便将函数灵活地传递给算法或动态控制其行为。 1. 可调用对象的绑定器绑定器的作用是将一个可调用对象的一部分参数提前绑定,从而生成一个新的可调用对象。 C++11 起引入了 std::bind,用于创建一个可调用对象并绑定部分参数;在现代 C++(C++20)中,更推荐使用 Lambda 表达式 替代 std::bind。 1.1 std::bindstd::bind 是一个函数模板,它可以接受一个可调用对象(如普通函数、成员函数、函数对象等)及部分参数,并返回一个新的可调用对象,该对象可以像函数一样调用。 语法123#include <functional> // std::bind 所在的头文件std::bind(callable, arg1, arg2, ..., argN); callable:要绑定的可调用对象。 arg1, arg2, ...,...
模板
模板(Template)概述模板是 C++ 中的一种泛型编程机制,允许编写通用的代码,可以在不指定具体数据类型的情况下定义函数、类或结构体。模板的主要目的是提供代码的复用性和灵活性,从而支持处理多种数据类型的能力。 C++ 中的模板主要分为两种: 函数模板(Function Template) 类模板(Class Template) 1. 函数模板函数模板是定义一个可以操作多种数据类型的函数。通过模板,函数可以在调用时根据传递的参数类型自动生成具体的函数。 1.1 函数模板的基本语法12345678910template <typename T>T add(T a, T b) { return a + b;}int main() { cout << add<int>(3, 4) << endl; // 显式指定类型为 int cout << add(3.5, 4.2) << endl; // 隐式推导类型为 double return...
c++中的线程
在 C++ 中,线程是用来实现并发编程的重要工具,它允许程序同时执行多个任务。C++11 标准引入了多线程支持,主要通过 <thread> 标头文件提供相关功能,包括线程创建、管理和同步等。 1. 基本概念 线程是程序执行的基本单位,一个程序可以包含多个线程。 多线程可以提高程序效率,特别是在多核 CPU 上,每个线程可以在不同的核上运行。 C++ 提供的多线程功能包括: 线程的创建与管理(std::thread)。 同步机制(如互斥锁 std::mutex、条件变量 std::condition_variable 等)。 数据保护(如线程安全的操作)。 2. 创建和管理线程1) 创建线程线程可以通过 std::thread 创建,并且可以使用函数、lambda 表达式或可调用对象作为线程入口。 (a) 使用普通函数123456789101112#include <iostream>#include <thread>void threadFunction() { std::cout <<...
智能指针
智能指针是一种在编程中管理动态内存资源的对象。它封装了原始指针(raw pointer),并提供额外的功能,例如自动释放资源、避免内存泄漏和管理对象的生命周期。智能指针广泛用于需要动态分配内存的语言(如 C++),通过 RAII(Resource Acquisition Is Initialization)原则实现内存管理。 在 C++ 中,智能指针主要在 <memory> 头文件中定义,包括以下几种类型: 1. std::unique_ptr 特点: 独占所有权(一个对象只能有一个 unique_ptr 拥有它)。 不可复制,但可以通过 std::move 转移所有权。 适合需要明确单一所有权的场景。 用法: 12345678#include <memory>#include <iostream>int main() { std::unique_ptr<int> ptr = std::make_unique<int>(42); // 创建智能指针 std::cout <<...
Lambda表达式
在 C++ 中,Lambda 表达式是一种轻量级的函数对象(或匿名函数),可以在代码中定义并直接使用。它是从 C++11 引入的功能,常用于需要定义短小函数的场景,比如多线程、STL 算法或回调函数中。 1. Lambda 表达式的基本语法123[捕获列表](参数列表) -> 返回类型 { 函数体}; **捕获列表**:定义 lambda 可以捕获哪些变量,以及如何捕获(按值或按引用)。 **参数列表**:和普通函数类似,定义函数的参数。 **返回类型**:可选,通常由编译器自动推断。 **函数体**:函数的逻辑部分。 2. Lambda 表达式的基本示例12345678910111213141516171819#include <iostream>#include <vector>#include <algorithm>int main() { // 最简单的 Lambda auto lambda = [] { std::cout <<...
c++11新特性之emplace
emplace 是 C++ 中标准库(STL)提供的一种高效的元素插入方式,常用于容器(如 std::vector, std::map, std::unordered_map 等)中。emplace 通过直接在容器内部构造元素,避免了不必要的拷贝或移动操作,从而提高了性能。 emplace 和 insert 的区别 **insert**:将一个已构造的对象插入到容器中。通常需要通过拷贝或移动构造将元素插入容器。 123std::vector<int> vec;int x = 5;vec.insert(vec.end(), x); // 插入时会发生一次拷贝构造 **emplace**:直接在容器内部构造元素,避免了额外的拷贝或移动操作。emplace 接受构造元素所需的参数,然后直接在容器中构造该元素。 12std::vector<int> vec;vec.emplace_back(5); // 在容器内部构造元素,避免拷贝 为什么使用 emplace? 避免不必要的拷贝或移动: insert...



