【C++】:C++11详解 —— 右值引用
目录
左值和右值
左值的概念
右值的概念
左值 vs 右值
左值引用 和 右值引用
左值引用
右值引用
左值引用 vs 右值引用
使用场景
左值引用的使用场景
左值引用的短板
右值引用的使用场景
1. 实现移动语义(资源高效转移)
2. 优化容器操作(如push_back、emplace_back)
3. 完美转发(Perfect Forwarding)
左值和右值
左值的概念
1、左值的定义
-
左值(lvalue) 是表示 对象身份(identity) 的表达式,即它指向一个 明确且持久的内存位置。
-
术语中的 "l" 最初源自赋值操作中出现在 左边 的值(如
a = 5中的a),但左值并不仅限于赋值左侧,也可以出现在右侧。
2、左值的关键特性
- 可寻址性:左值对应具体的内存地址,可通过取地址操作符(
&)获取其地址。
int x = 10;
int *p = &x; // x 是左值,可取其地址
- 可修改性(除非被 const 限定):左值通常可被赋值,除非被声明为
const。
int a = 5;
a = 20; // 合法,a 是左值
const int b = 10;
b = 30; // 非法,b 是 const 左值,不可修改
-
持久性:左值代表的对象的生命周期超出其所在的表达式(如变量、数组元素等)。
3、代码示例
int x = 5; // x 是左值,5 是右值int y = x; // x 作为右值使用(取其值)x = y + 10; // x 是左值,y+10 的结果是右值int *p = &x; // &x 合法(x 是左值)// &5; // 非法,5 是右值,无地址const int c = 20; // c 是左值(可寻址),但不可修改// c = 30; // 非法return 0;
右值的概念
右值(rvalue)是编程语言(如C/C++)中的另一个核心概念,与左值(lvalue)相对。右值的核心特征是表示一个 临时的、不可寻址的值,通常用于计算或赋值操作中的右侧。
1、右值的定义
-
右值(rvalue) 是表示 数据值(value) 的表达式,其核心是提供某个具体的值,而非持久的内存位置。
-
术语中的 "r" 最初源自赋值操作中只能出现在 右侧 的值(如
a = 5中的5),但右值的含义在现代语言中更为复杂(尤其在C++中支持右值引用后)。
2、右值的关键特性
-
不可寻址性:右值通常是临时的,没有明确的内存地址,不能通过取地址操作符(
&)获取其地址。
int x = 5;
int y = x + 10; // x + 10 是右值,无法写 &(x + 10)
- 不可修改性:右值本身是只读的,不能直接修改。
int a = 5;
5 = a; // 非法,5 是右值,不可赋值
a + 1 = 10; // 非法,a + 1 是右值
-
短暂的生命周期:右值通常是临时计算结果或字面量,生命周期仅限于当前表达式。
3、右值的常见形式
-
字面量:如
5、"hello"、3.14。 -
临时对象:如函数返回的非引用类型值(
int func() { return 42; },func()是右值)。 -
算术/逻辑表达式的结果:如
a + b、x < y。 -
隐式转换生成的临时对象:如类型转换后的值(
float(5))。 -
C++中的右值引用(C++11起):如
std::move(x)返回的右值引用。
左值 vs 右值
| 特征 | 左值 | 右值 |
|---|---|---|
| 内存地址 | 有明确地址(可寻址) | 无地址(不可寻址) |
| 生命周期 | 持久(超出当前表达式) | 短暂(表达式结束即销毁) |
| 赋值操作 | 可出现在赋值左侧(除非const) | 只能出现在右侧 |
| 典型示例 | 变量、解引用指针 | 字面量、临时结果、函数返回值 |
左值引用 和 右值引用
左值引用
左值引用是C++中用于为现有对象创建别名的一种机制,允许通过引用直接访问或修改原对象。
左值引用的定义
-
左值引用(lvalue reference)是绑定到左值的引用,用
&声明。 -
必须初始化且无法重新绑定到其他对象。
-
核心作用:避免对象拷贝、允许函数直接修改参数、实现更高效的操作。
基本语法与规则
类型& 引用名 = 左值;
-
必须初始化:引用声明时必须绑定到一个左值。
-
不可重新绑定:引用一旦初始化,无法更改指向的对象。
-
不可绑定到右值(除非使用
const):
int x = 10;
int& ref = x; // ref是x的别名
ref = 20; // 修改ref即修改x的值(x变为20)int& r1 = 5; // 错误:右值不能绑定到非const左值引用
const int& r2 = 5; // 正确:const左值引用可绑定到右值
右值引用
右值引用(rvalue reference)是C++11引入的核心特性,旨在支持 移动语义 和 完美转发,从而提升程序效率。
右值引用的定义
-
右值引用 用
&&声明,专门绑定到 右值(临时对象、字面量等)。 -
核心目的:允许资源(如动态内存、文件句柄)的高效转移,避免不必要的拷贝。
int&& rref = 42; // 绑定到字面量(右值)
std::string&& s = func(); // 绑定到函数返回的临时对象
关键特性
-
绑定到右值:只能绑定到即将销毁或临时的对象,不能直接绑定到左值(除非使用
std::move)。
int x = 10;
int&& r1 = x; // 错误:x是左值
int&& r2 = std::move(x); // 正确:std::move将左值转换为右值引用
- 移动语义:通过移动构造函数和移动赋值运算符,直接“窃取”资源,避免深拷贝。
class MyVector
{
public:// 移动构造函数MyVector(MyVector&& other) noexcept : data_(other.data_), size_(other.size_) {other.data_ = nullptr; // 置空源对象指针other.size_ = 0;}// 移动赋值运算符MyVector& operator=(MyVector&& other) noexcept {if (this != &other) {delete[] data_;data_ = other.data_;size_ = other.size_;other.data_ = nullptr;other.size_ = 0;}return *this;}private:int* data_;size_t size_;
};
- 完美转发:通过
std::forward保持参数原始值类别(左值/右值),实现无损传递。
template<typename T>
void wrapper(T&& arg)
{// 保持arg的原始值类别(左值或右值)target_func(std::forward<T>(arg));
}
总结
右值引用的核心价值在于:
-
资源高效转移:通过移动语义减少拷贝开销。
-
完美转发:在泛型编程中精确传递参数。
-
现代C++基础:支持智能指针、容器优化等高级特性。
理解右值引用是掌握现代C++性能优化的关键步骤。
左值引用 vs 右值引用
| 特性 | 左值引用 (&) | 右值引用 (&&) |
|---|---|---|
| 绑定对象 | 左值(具名对象、持久内存) | 右值(临时对象、即将销毁的值) |
| 用途 | 操作现有对象 | 移动语义、资源高效转移 |
| 可修改性 | 允许修改(除非 const) | 通常用于“窃取”资源,避免拷贝 |
| 示例 | int& r = x; | int&& r = std::move(x); |
使用场景
左值引用的使用场景
左值引用(&)在C++中用途广泛,核心目标是 避免不必要的拷贝、直接操作原对象。
1. 函数参数传递(修改实参)
场景:函数需要修改外部变量,或传递大型对象(如容器、类实例)时避免拷贝。
// 交换两个变量的值
void swap(int& a, int& b)
{int temp = a;a = b;b = temp;
}int main()
{int x = 10, y = 20;swap(x, y); // x=20, y=10(直接修改原对象)
}
2. 函数返回左值引用(返回可修改的别名)
场景:返回容器元素、类成员或链式赋值操作。
// 返回数组元素的引用,允许直接修改
int& getElement(int arr[], int index)
{return arr[index];
}int main()
{int arr[5] = {1, 2, 3, 4, 5};getElement(arr, 2) = 100; // arr[2] = 100
}
3. 范围for循环修改容器元素
场景:遍历容器(如vector、array)时直接修改元素。
std::vector<int> vec = {1, 2, 3, 4};
for (int& num : vec)
{num *= 2; // 直接修改vec中的元素
}
// vec变为 {2, 4, 6, 8}
4. 实现操作符重载
场景:重载赋值操作符或输入输出流操作符时,返回左值引用以支持链式操作。
class MyClass
{
public:MyClass& operator=(const MyClass& other) {// 赋值逻辑return *this; // 返回左值引用以支持连续赋值(a = b = c)}
};// 输出流重载
std::ostream& operator<<(std::ostream& os, const MyClass& obj)
{os << obj.data;return os; // 返回流引用以支持链式输出(cout << a << b)
}
5. 与
const结合,接受右值或只读访问
场景:函数需要兼容左值和右值参数,或避免拷贝但禁止修改。
// 常量左值引用可绑定到右值
void print(const std::string& s)
{std::cout << s;
}int main()
{print("Hello"); // 接受右值(临时字符串)std::string str = "World";print(str); // 接受左值
}
6. 实现链式调用(Fluent Interface)
场景:通过返回对象自身的引用,支持连续方法调用。
class StringBuilder
{
private:std::string data;
public:StringBuilder& append(const std::string& s) {data += s;return *this; // 返回自身引用}
};int main()
{StringBuilder sb;sb.append("Hello").append(" ").append("World"); // 链式调用
}
7. 作为类成员,实现别名或代理模式
场景:类内部持有对其他对象的引用,避免拷贝。
class Window
{
private:RenderContext& context; // 引用外部渲染上下文
public:Window(RenderContext& ctx) : context(ctx) {}void draw() {context.render(); // 直接操作外部对象}
};
左值引用的短板
1. 悬空引用(Dangling Reference)
问题:左值引用必须绑定到有效对象,但若引用的对象被销毁(如局部变量、临时对象),引用将指向无效内存,导致未定义行为(UB)。
总结就是出了函数,变量还是存在,就可以引用返回
int& createDanglingRef()
{int x = 10;return x; // 错误:x在函数结束时销毁,返回的引用无效!
}int main()
{int& ref = createDanglingRef(); // ref成为悬空引用std::cout << ref; // 未定义行为(可能崩溃或输出垃圾值)
}// 解决
// 1、避免返回局部变量的引用。
// 2、若需返回引用,确保其指向生命周期更长的对象(如静态变量、堆内存或参数传入的对象)。
2. 无法直接绑定到右值(除非使用
const)
问题:非 const 左值引用不能绑定到右值(如字面量、临时对象),限制了函数参数的灵活性。
void modify(int& value) { value++; }int main()
{modify(5); // 错误:5是右值,不能绑定到非const左值引用
}// 解决
// 1、使用 const 左值引用:允许绑定到右值,但禁止修改。
void readOnly(const int& value) { /* 只读操作 */ }
readOnly(5); // 合法// 2、重载函数或使用右值引用(C++11+)
void modify(int&& value) { /* 处理右值 */ }
modify(5); // 合法
3. 可能引发意外的数据修改
问题:若函数参数为非 const 左值引用,调用者可能未意识到传入的对象会被修改,导致逻辑错误。
void process(std::vector<int>& data)
{data.clear(); // 清空外部数据(调用者可能未预料到)
}int main()
{std::vector<int> myData = {1, 2, 3};process(myData); // myData被意外清空
}
4. 无法实现资源的高效转移
问题:左值引用只能操作现有对象,无法直接利用右值(临时对象)的资源,导致不必要的拷贝。
class HeavyObject
{
public:HeavyObject(const HeavyObject& other) { /* 深拷贝(开销大)*/ }
};void useObject(HeavyObject& obj) { /* 操作obj */ }int main()
{HeavyObject obj;useObject(obj); // 合法,但无法优化临时对象的构造// useObject(HeavyObject()); // 错误:右值不能绑定到非const左值引用
}// 解决
// 1、结合右值引用(C++11+):实现移动语义,避免拷贝。
void useObject(HeavyObject&& obj) { /* 移动资源 */ }
useObject(HeavyObject()); // 合法,触发移动语义
6. 不适用于需要“移动”语义的场景
问题:左值引用无法直接支持资源的高效转移(如 std::vector 的重新分配内存),需依赖拷贝操作。
std::vector<std::string> oldData;
// 假设需要将oldData的内容转移到新容器
std::vector<std::string> newData = oldData; // 深拷贝(性能差)// 解决
// 1、使用右值引用和移动语义:
std::vector<std::string> newData = std::move(oldData); // 移动而非拷贝
总结与最佳实践
| 短板 | 解决方案 |
|---|---|
| 悬空引用 | 确保引用绑定到有效对象,避免返回局部变量引用。 |
| 无法绑定右值 | 使用 const 左值引用或重载右值引用版本。 |
| 意外修改 | 优先用 const 引用传递只读参数,明确函数副作用。 |
| 资源转移效率低 | 结合右值引用实现移动语义。 |
| 生命周期管理复杂 | 使用智能指针、明确所有权,避免跨作用域引用。 |
C++11提出右值引用就是为了解决左值引用的短板的,但解决方式并不是简单的将右值引用作为函数的返回值
右值引用的使用场景
右值引用(&&)是C++11引入的核心特性,主要用于 移动语义 和 完美转发,
1. 实现移动语义(资源高效转移)
场景:避免深拷贝大型对象(如容器、动态资源类),直接“窃取”资源所有权。
class DynamicArray
{
private:int* data_;size_t size_;
public:// 移动构造函数(从临时对象“窃取”资源)DynamicArray(DynamicArray&& other) noexcept : data_(other.data_), size_(other.size_) {other.data_ = nullptr; // 置空原对象,避免重复释放other.size_ = 0;}// 移动赋值运算符DynamicArray& operator=(DynamicArray&& other) noexcept {if (this != &other) {delete[] data_; // 释放当前资源data_ = other.data_; // 接管资源size_ = other.size_;other.data_ = nullptr;other.size_ = 0;}return *this;}~DynamicArray() { delete[] data_; }
};int main()
{DynamicArray a;DynamicArray b = std::move(a); // 触发移动构造函数,避免深拷贝
}
2. 优化容器操作(如push_back、emplace_back)
C++11标准出来之后,STL中的容器都增加了移动构造和移动赋值。
string 类
vector 类

std::vector<std::string> vec;
// 添加临时对象(右值)
vec.push_back("Hello"); // C++11前:构造临时string,深拷贝到容器
vec.push_back(std::string("World")); // C++11后:移动临时对象,避免拷贝// 更高效的方式:直接构造元素(C++11的emplace_back)
vec.emplace_back("Hello"); // 直接在容器内存中构造,无拷贝或移动
3. 完美转发(Perfect Forwarding)
场景:完美转发(Perfect Forwarding)是C++11引入的核心机制,用于在泛型编程中精确传递参数的 值类别(左值/右值)和 类型,避免不必要的拷贝或类型损失。
为什么需要完美转发?
在多层函数调用中,若直接将参数传递给其他函数,参数的 值类别(左值/右值) 可能丢失,导致:
-
无法触发移动语义:右值被当作左值处理,引发不必要的拷贝。
-
重载匹配错误:目标函数可能无法正确调用左值或右值版本的重载。
template<typename T>
void relay(T arg)
{target(arg); // 传递时arg始终是左值,右值属性丢失!
}void target(int& x) { std::cout << "左值版本\n"; }
void target(int&& x) { std::cout << "右值版本\n"; }int main()
{int x = 5;relay(x); // 期望调用左值版本relay(10); // 期望调用右值版本,但实际调用左值版本!
}
// 输出始终为 左值版本,因为 arg 在 relay 函数内部是左值。
完美转发的实现
通过 通用引用(Universal Reference) 和 std::forward 实现:
-
通用引用(
T&&):模板参数T&&可同时绑定到左值和右值,保留参数的原始值类别。 -
std::forward<T>:根据T的原始类型,有条件地将参数转换为左值或右值引用。
注意:const T&& 不符合通用引用的语法形式:多了一个 const 修饰符。
修正后的代码:
template<typename T>
void relay(T&& arg) // 通用引用接受左值或右值
{target(std::forward<T>(arg)); // 完美转发
}void target(int& x) { std::cout << "左值版本\n"; }
void target(int&& x) { std::cout << "右值版本\n"; }int main()
{int x = 5;relay(x); // 调用左值版本relay(10); // 调用右值版本relay(std::move(x)); // 调用右值版本
}
完美转发的核心机制
-
通用引用(
T&&)-
当模板参数为
T&&且T需推导时,T&&成为通用引用。 -
可绑定到左值或右值,并保留原始值类别信息(通过
T的类型推导)。
传入参数类型 T推导结果arg类型左值( int&)int&int& &&→int&右值( int&&)intint&& -
-
std::forward<T>的原理-
若
T为左值引用(T = int&),std::forward<T>返回左值引用。 -
若
T为非引用(如int,表示原始参数是右值),std::forward<T>返回右值引用。 -
等效于:
static_cast<T&&>(arg)。
-
应用场景
1、容器操作(如 emplace_back)
直接在容器内部构造元素,避免临时对象的拷贝或移动。
std::vector<std::string> vec;
vec.emplace_back("Hello"); // 直接在vec内存中构造string,无拷贝
完美转发 vs.
std::move
| 特性 | std::forward | std::move |
|---|---|---|
| 用途 | 保留参数原始值类别(左值/右值) | 强制转换为右值引用(用于移动) |
| 条件性 | 根据模板参数 T 决定是否转换 | 无条件转换 |
| 典型场景 | 泛型编程中的参数转发 | 明确需要转移资源所有权的场景 |
注意事项
1、避免多次转发:同一参数被多次 std::forward 可能导致悬空引用(如移动后的对象被重复使用)。
template<typename T>
void relay(T&& arg)
{target1(std::forward<T>(arg));target2(std::forward<T>(arg)); // 危险!arg可能已被移动
}
2、通用引用与重载的冲突:通用引用模板可能匹配过于广泛,导致与其他重载冲突。
template<typename T>
void foo(T&& arg) { /*...*/ }void foo(int x) { /*...*/ } // 重载可能被通用引用版本掩盖
3、const 限定符的处理:若参数有 const 修饰,需在转发时保留。
template<typename T>
void relay(const T&& arg) // 注意:此处是右值引用,非通用引用!
{target(std::forward<const T>(arg));
}
相关文章:
【C++】:C++11详解 —— 右值引用
目录 左值和右值 左值的概念 右值的概念 左值 vs 右值 左值引用 和 右值引用 左值引用 右值引用 左值引用 vs 右值引用 使用场景 左值引用的使用场景 左值引用的短板 右值引用的使用场景 1. 实现移动语义(资源高效转移) 2. 优化容器操作&a…...
【css酷炫效果】纯CSS实现虫洞穿越效果
【css酷炫效果】纯CSS实现穿越效果 缘创作背景html结构css样式完整代码基础版进阶版(虫洞穿越) 效果图 想直接拿走的老板,链接放在这里:https://download.csdn.net/download/u011561335/90491973 缘 创作随缘,不定时…...
Linux IP 配置
Linux IP 配置 1 环境介绍2 网卡信息配置3 使用nmtui工具配置4 更多Linux命令学习使用列表 1 环境介绍 虚拟机,服务器安装系统完成后,先要配置ip 地址,这样可以方便远程若是物理服务器一般会有4个网卡信息麒麟v10,CentOS7&#x…...
设计模式之装饰器模式:原理、实现与应用
引言 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象动态添加新的行为。装饰器模式提供了一种灵活的替代方案,避免了通过继承扩展功能的局限性。本文将深入探讨装…...
c语言笔记 结构体基础
目录 基础知识 结构体定义 基础知识 在c语言中变量是有类型的,比如整型,char型,浮点型等,这些都是单一的类型,那么如果说我要定义一个学生的信息,那么这些单一的类型是不足以表达一个学生的全部信息&#…...
Vue 登录 记住密码,设置存储时间
Vue 登录 记住密码,设置存储时间 一、手动存储login.vue 二、使用vue-cookies插件main.jslogin.vue 一、手动存储 login.vue 提示: // 设置cookie方法 setCookie(loginName, password, days) {let text encryptDes(password, des123)//使用des方法加…...
C++ 学习笔记(三)—— 入门+类和对象
1、内联函数(inline) 内联函数主要是解决C语言的宏的缺陷提出来的; 宏的缺陷: 1)容易出错,语法坑很多; 2)不能调试; 3)没有类型安全的检查; 宏的…...
KVM安全模块生产环境配置与优化指南
KVM安全模块生产环境配置与优化指南 一、引言 在当今复杂多变的网络安全环境下,生产环境中KVM(Kernel-based Virtual Machine)的安全配置显得尤为重要。本指南旨在详细阐述KVM安全模块的配置方法,结合强制访问控制(M…...
基于 SSE 和 WebSocket 的在线文本实时传输工具
简介 在线文本实时传输工具支持 SSE(Server-Sent Events) 和 WebSocket,可在不同设备间快速共享和同步文本,适用于跨设备协作、远程办公和即时通讯。 核心功能 实时同步:文本输入后,另一端用户可立即看到…...
数图亮相第三届全国生鲜创新峰会,赋能生鲜零售数字化转型
2025年3月15-18日,第三届全国生鲜创新峰会在湖北宜昌召开,主题为“生鲜破局,重塑价值”。峰会汇聚行业专家、企业领袖及精英,探讨生鲜零售新机遇与挑战。作为领先的“智慧零售”服务商,数图信息科技受邀出席࿰…...
go 安装swagger
1、依赖安装: # 安装 swag 命令行工具 go install github.com/swaggo/swag/cmd/swaglatest# 安装 gin-swagger 和 swagger 文件的依赖 go get -u github.com/swaggo/gin-swagger go get -u github.com/swaggo/files 2、测试 cmd中输入: swag -v 3、…...
CH347使用笔记:CH347结合STM32CubeIDE实现单片机下载与调试
目录 基于 STM32CubeIDE的 CH347 JTAG/SWD调试器使用说明1. CH347驱动安装与配置2. STM32CubeIDE调试器配置2.1 打开相关工程后,进行以下操作2.2 openocd.exe替换2.3 脚本添加2.4 更改调试器选择 3. 下载程序4. 使用过程中可能遇到的问题4.1 CH347未插入4.2 Openocd…...
从C语言开始的C++编程生活(1)
前言 本系列文章承接C语言的学习,需要有C语言的基础才能学会哦。 第1篇主要讲的是有关于C的命名空间、输入和输出。 C才起步,都很简单呢! 目录 前言 命名空间namespace 基本语法 作用 使用命名空间 域作用限定符 :: 基本语法 using n…...
Python F-String 深度解析:原理、用法与最佳实践
# Python F-String 深度解析:原理、用法与最佳实践 ## 一、引言 Python 的 F-String(格式化字符串字面值)自 3.6 版本引入以来,凭借其简洁性和高效性,迅速成为字符串格式化的首选方案。本文将从原理、核心用法和编码规…...
智能家居分享
因为最近沉迷智能家居,所以来给大家分享一些轻松改变生活体验的小家具 1: 智能门锁 出门忘记带钥匙是许多人都遇到过的尴尬事,智能门锁的出现完美解决了这个困扰。智能门锁采用指纹识别、密码、刷卡、手机等多种开锁方式,大大增…...
20. Excel 自动化:Excel 对象模型
一 Excel 对象模型是什么 Excel对象模型是Excel图形用户界面的层次结构表示,它允许开发者通过编程来操作Excel的各种组件,如工作簿、工作表、单元格等。 xlwings 是一个Python库,它允许Python脚本与Excel进行交互。与一些其他Python库&#x…...
解决uni-app授权弹框华为审核拒绝
背景: 在使用定位、相机、文件、电话,需要用户同意授权时,华为和vivo需要告知用户使用权限目的。 方案: 在uni授权时,弹框告诉授权目的,效果如下: 代码: const perListener {//…...
施耐德PLC仿真软件Modbus tcp通讯测试
安装仿真软件:EcoStruxure™ Control Expert - PLC 仿真器 下载地址:https://www.schneider-electric.cn/zh/download/document/EIO0000001719/ 配置CPU: 切换至仿真模式,系统托盘中出现仿真器图标 新建变量test,地址…...
软考 中级软件设计师 考点知识点笔记总结 day05
文章目录 4、栈和队列4.1、栈的定义4.2、队列定义 5、串、数组、矩阵和广义表5.1、串5.2、 数组5.3、稀疏矩阵5.4、广义表 4、栈和队列 4.1、栈的定义 线性表是具有相同数据类型的n个数据元素的有限序列, n为表厂。n0时 线性表是一个空表 L (a1,a2,a3…...
1.排序算法(学习自用)
1.冒泡排序 算法步骤 相邻的元素之间对比,每次早出最大值或最小值放到最后或前面,所以形象的称为冒泡。 特点 n个数排序则进行n轮,每轮比较n-i次。所以时间复杂度为O(n^2),空间复杂度为O(1),该排序算法稳定。 代码…...
vs2017版本与arcgis10.1的ArcObject SDK for .NET兼容配置终结解决方案
因电脑用的arcgis10.1,之前安装的vs2010正常能使用AO和AE,安装vs2017后无法使用了,在重新按照新版本arcgis engine或者arcObject费时费力,还需要重新查找资源。 用vs2017与arc10.1的集成主要两个问题,1:安装后vs中没有…...
基于yolo11+flask打造一个精美登录界面和检测系统
这个是使用flask实现好看登录界面和友好的检测界面实现yolov11推理和展示,代码仅仅有2个html文件和一个python文件,真正做到了用最简洁的代码实现复杂功能。 测试通过环境: windows x64 anaconda3python3.8 ultralytics8.3.81 flask1.1.…...
用 Vue 3.5 TypeScript 重新开发3年前甘特图的核心组件
回顾 3年前曾经用 Vue 2.0 开发了一个甘特图组件,如今3年过去了,计划使用Vue 3.5 TypeScript 把组件重新开发,有机会的话再开发一个React版本。 关于之前的组件以前文章 Vue 2.0 甘特图组件 下面录屏是是 用 Vue 3.5 TypeScript 开发的目前…...
深入解析 SQL 事务:确保数据一致性的关键
SQL 事务 什么是 SQL 事务?事务的 ACID 特性原子性(Atomicity):示例: 一致性(Consistency):示例: 隔离性(Isolation):持久性(Durability):示例&am…...
复习JVM
JVM的三个主要主题: 1.java内存区域划分: a. 堆 b. 栈 c. 元数据区 d. 程序计数器 2. 类加载 a. 加载: 打开.class文件, 读取内容 b. 验证: 验证.class文件的格式是否符合要求. c. 准备: 给类对象分配内存空间 d. 解析: 初始化字符串常量 e. 初始化: 对类对象中的各个…...
C++程序设计语言笔记——抽象机制:元编程
0 使用元编程提高类型安全。 使用元编程提升类型安全的核心在于通过代码生成、编译时检查或类型约束自动化来减少运行时错误。以下分不同编程范式详细说明实现方案: 一、静态类型语言的编译期约束(以C为例) template<typename T> cl…...
基于STM32的火灾报警设备(阿里云平台)
目录 前言: 一、项目介绍和演示视频 二、硬件需求准备 三、硬件框图 1. 原理图 2. PCB 四、CubeMX配置 五、代码框架 前言: 源代码下载链接: https://download.csdn.net/download/m0_74712453/90474701 需要实物的可以私信博主或者…...
用uv管理python环境/项目(各种应用场景)
一、安装uv 有python的情况 pip install uvWindows powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"linux或macOS curl -LsSf https://astral.sh/uv/install.sh | sh二、换镜像源 uv不会读取pip的镜像源配置,所…...
java面试题之多线程
java面试题之多线程 什么是线程?什么是线程安全和线程不安全?什么是⾃旋锁?什么是CAS?什么是乐观锁和悲观锁?什么是AQS?什么是原⼦操作?在Java Concurrency API中有哪些原⼦类(atomic classes)&…...
FPGA-流水灯
Quartus中使用Verilog实现 根据之前所学内容,打开Quartus 软件,新建FPGA项目文件,建立好空项目过后,选择Verilog HDL File,因为我们要使用Verilog代码实现仿真。 详细操作可参考往期博客: FPGA 实验报告&a…...
