C++11_2
文章目录
- 前言
- 一、新的类功能——新的默认成员函数
- 1. 编译器默认生成的移动构造与移动赋值
- 2. 手动提供移动构造或移动赋值的影响
- 二、可变参数模板
- 1. 多参数
- 1. 可变参数模板的基础
- 2. 可变参数模板的展开
- (1)递归展开参数包
- (2)使用逗号表达式展开参数包
- 3. 实际应用场景
- 三、STL容器中的empalce相关接口函数
- 1. empalce_back用法
- 2. emplace_back与push_back与优缺
- 四、包装器
- 1. function包装器
- (1)function是什么?
- (2)function语法
- (3)function应用
- 2. bind
- (1)bind语法
- (2)bind用处
- (3)对于成员函数
- 总结
前言
接下来我们接着看C++11的新功能吧~
一、新的类功能——新的默认成员函数
这里是你的内容经过格式优化后的版本,保证清晰、易读,并符合技术文档的风格:
C++11 新增:移动构造函数与移动赋值运算符
C++11 新增了移动构造函数和移动赋值运算符重载,它们主要用于资源所有权转移,提高性能,减少不必要的拷贝操作。
1. 编译器默认生成的移动构造与移动赋值
在特定条件下,编译器会自动生成默认的移动构造函数和移动赋值运算符。但需要注意以下几点:
- 默认移动构造函数
- 如果类没有定义:
- 析构函数
- 拷贝构造函数
- 拷贝赋值运算符
- 那么编译器会自动生成默认的移动构造函数。
- 其行为:
- 对于内置类型(如
int
、double
),执行按字节逐成员拷贝。 - 对于自定义类型,如果该类型实现了移动构造,则调用其移动构造;否则调用拷贝构造。
参考代码——string类
- 对于内置类型(如
- 如果类没有定义:
namespace jyf
{class string{public:typedef char* iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}string(const char* str = ""):_size(strlen(str)), _capacity(_size){cout << "string(const char* str)" << endl;_str = new char[_capacity + 1];strcpy(_str, str);}// s1.swap(s2)void swap(string& s){::swap(_str, s._str);::swap(_size, s._size);::swap(_capacity, s._capacity);}// 拷贝构造string(const string& s):_str(nullptr){cout << "string(const string& s) -- 深拷贝" << endl;//string tmp(s._str);//swap(tmp);}string(string&& s):_str(nullptr){cout << "string(string&& s) -- 移动拷贝" << endl;swap(s);}// 赋值重载string& operator=(const string& s){cout << "string& operator=(string s) -- 深拷贝" << endl;string tmp(s);swap(tmp);return *this;}string& operator=(string&& s){cout << "string& operator=(string && s) -- 移动拷贝" << endl;swap(s);return *this;}~string(){delete[] _str;_str = nullptr;}char& operator[](size_t pos){assert(pos < _size);return _str[pos];}void reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}void push_back(char ch){if (_size >= _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;++_size;_str[_size] = '\0';}//string operator+=(char ch)string& operator+=(char ch){push_back(ch);return *this;}const char* c_str() const{return _str;}private:char* _str;size_t _size;size_t _capacity; // 不包含最后做标识的\0};
}
这里我们采用如下代码来进行学习:
class Person
{
public:Person(const char* name = "", int age = 0):_name(name), _age(age){}//想让他强制生成就用关键字default,如下所示//Person(Person&& p) = default;//Person(const Person& p) = default;private:jyf::string _name;int _age;
};int main()
{Person s1;Person s2 = s1;Person s3 = std::move(s1);return 0;
}
如上述代码所示,person类没有实现析构,拷贝构造,拷贝赋值,因此传右值的时候就因该调到移动拷贝。
- 默认移动赋值运算符
- 如果类没有定义:
- 析构函数
- 拷贝构造函数
- 拷贝赋值运算符
- 那么编译器会自动生成默认的移动赋值运算符。
- 其行为:
- 对于内置类型,执行按字节逐成员拷贝。
- 对于自定义类型,如果该类型实现了移动赋值,则调用其移动赋值;否则调用拷贝赋值。
- 如果类没有定义:
注意:默认移动赋值运算符的行为与默认移动构造函数完全类似。
2. 手动提供移动构造或移动赋值的影响
如果类手动实现了:
- 移动构造函数
- 移动赋值运算符
那么编译器不会自动提供:
- 拷贝构造函数
- 拷贝赋值运算符
如果你的类需要支持拷贝与移动,必须手动实现拷贝构造与拷贝赋值,否则可能导致拷贝操作被禁止(=delete
)。
二、可变参数模板
1. 多参数
C++11 引入了可变参数模板,允许创建可以接受任意数量参数的函数模板和类模板。
1. 可变参数模板的基础
在可变参数模板中,参数列表使用 ...
省略号表示。例如:
template <class ...Args>
void ShowList(Args... args)
{}
在上面的代码中:
Args...
是模板参数包,它可以包含**0 到 N(N ≥ 0)**个模板参数。args...
是函数形参包,它与Args...
一一对应。
可变参数模板的一个主要特点是:
不能直接获取参数包中的元素,只能通过展开参数包的方式访问每个参数。这也是可变参数模板最难理解的地方,因为语法不支持 args[i]
这种方式直接访问参数。
2. 可变参数模板的展开
由于无法直接访问参数包中的元素,常见的展开方式有:
(1)递归展开参数包
递归展开是最常见的方式,我们通过递归终止函数来控制递归的结束:
#include <iostream>
using namespace std;// 递归终止函数
template <class T>
void ShowList(const T& t)
{cout << t << endl;
}// 递归展开函数
template <class T, class ...Args>
void ShowList(T value, Args... args)
{cout << value << " ";ShowList(args...);
}int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0;
}
执行结果:
1
1 A
1 A sort
原理:
- 递归终止函数:当
Args...
为空时,调用ShowList(const T&)
结束递归。 - 递归展开:每次调用
ShowList(T value, Args... args)
,打印value
,然后递归调用ShowList(args...)
继续展开。
也可以这样:
void _ShowList()
{// 结束条件的函数cout << endl;
}template <class T, class ...Args>
void _ShowList(T val, Args... args)
{cout << val << " ";_ShowList(args...);
}//args代表0-N的参数包
template <class ...Args>
void CppPrint(Args... args)
{_ShowList(args...);
}int main()
{CppPrint();CppPrint(1);CppPrint(1, 2);CppPrint(1, 2, 2.2);CppPrint(1, 2, 2.2, string("xxxx"));// ...return 0;
}
(2)使用逗号表达式展开参数包
逗号表达式可以用于参数包展开,不需要额外定义递归终止函数:
#include <iostream>
using namespace std;template <class T>
void PrintArg(T t)
{cout << t << " ";
}// 直接展开函数
template <class ...Args>
void ShowList(Args... args)
{int arr[] = { (PrintArg(args), 0)... }; // 逗号表达式展开参数包cout << endl;
}int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0;
}
执行结果:
1
1 A
1 A sort
原理:
PrintArg(args)
依次执行PrintArg(arg1)
,PrintArg(arg2)
,PrintArg(arg3)...
- 由于
int arr[] = { (PrintArg(args), 0)... };
是一个初始化列表,所以所有PrintArg(args)
在构造数组时就被执行,从而展开参数包。
3. 实际应用场景
我们来看一个实用一点的实际场景:
class Date
{
public:Date(int year = 1, int month = 1, int day = 1):_year(year),_month(month),_day(day){cout << "Date构造" << endl;}Date(const Date& d):_year(d._year), _month(d._month), _day(d._day){cout << "Date拷贝构造" << endl;}private:int _year;int _month;int _day;
};template <class ...Args>
Date* Create(Args... args)
{Date* ret = new Date(args...);return ret;
}int main()
{Date* p1 = Create();Date* p2 = Create(2023);Date* p3 = Create(2023, 9);Date* p4 = Create(2023, 9, 27);Date d(2023, 1, 1);Date* p5 = Create(d);return 0;
}
如下图所示:有了多参数之后,我们只要提供多参数的构造,再将构造函数写缺省,就可以更加灵活多变的传参来创建对象,和传统对象的创建相比,这个方法不需要创建额外的对象,参数包
传过去会自动匹配
构造函数,省去了一层拷贝,提高了效率!
也可以直接传日期类对象,参数包接收就会掉拷贝构造:
三、STL容器中的empalce相关接口函数
1. empalce_back用法
http://www.cplusplus.com/reference/vector/vector/emplace_back/
http://www.cplusplus.com/reference/list/list/emplace_back/
我们可以看到每一个容器都新增了empalce系类的内容,那么它有什么用呢?
template <class... Args>
void emplace_back (Args&&... args);
首先我们看到的emplace系列的接口,支持模板的可变参数,并且万能引用。那么相对insert和
emplace系列接口的优势到底在哪里呢?
2. emplace_back与push_back与优缺
int main()
{list< std::pair<int, char> > mylist;// emplace_back支持可变参数,拿到构建pair对象的参数后自己去创建对象// 那么在这里我们可以看到除了用法上,和push_back没什么太大的区别mylist.emplace_back(10, 'a');mylist.emplace_back(20, 'b');mylist.emplace_back(make_pair(30, 'c'));mylist.push_back(make_pair(40, 'd'));mylist.push_back({ 50, 'e' });for (auto e : mylist)cout << e.first << ":" << e.second << endl;return 0;
}
主要是这样:mylist.emplace_back(20, 'b');
,这样就不用先创建临时对象在进行拷贝构造,而是直接走参数包,有一定性能提升的。而push_back只能传对象。
我们再来看下一个场景:
int main()
{// 下面我们试一下带有拷贝构造和移动构造的jyf::string,再试试呢// 我们会发现其实差别也不大,emplace_back是直接构造了,push_back// 是先构造,再移动构造,其实也还好。std::list< std::pair<int, jyf::string> > mylist;mylist.emplace_back(10, "sort");mylist.push_back(make_pair(30, "sort"));std::list<Date> lt;Date d(2023, 9, 27);// 只能传日期类对象lt.push_back(d);// 传日期类对象// 传日期类对象的参数包// 参数包,一路往下传,直接去构造或者拷贝构造节点中日期类对象lt.emplace_back(d);lt.emplace_back(2023, 9, 27);return 0;
}
因为有移动构造的存在,所以对于深拷贝的类其实差别不大,对于浅拷贝有一定提升,但因为浅拷贝本来就没有多少资源,所以也影响不大。
四、包装器
1. function包装器
function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。
那么,function有什么用呢?
function在#include <functional>
里面~
(1)function是什么?
我们来看下面一段代码:
#include<iostream>
using namespace std;
#include <functional>template<class F, class T>
T useF(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return f(x);
}double f(double i)
{return i / 2;
}struct Functor
{double operator()(double d){return d / 3;}
};int main()
{// 函数指针cout << useF(f, 11.11) << endl;// 函数对象cout << useF(Functor(), 11.11) << endl;// lambda表达式cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;return 0;
}
有三类:1.函数指针 2. 函数对象 3. lambda表达式 分别去调用useF函数,但是他们三个虽然都是起到类似定义函数变量的作用,但是他们却实例化出三份不同的函数,证据就是运行结果静态变量没有则会增加到3,而是有3个1。
那有没有什么方法可以包装一下这三类1.函数指针 2. 函数对象 3. lambda表达式
呢?
有的兄弟,有的~
我们的包装器就要登场了——function
(2)function语法
语法:function<返回值类型(参数列表)> xxx = ???
像这样:
// 包装器 -- 可调用对象的类型问题function<double(double)> f1 = f;function<double(double)> f2 = [](double d)->double { return d / 4; };function<double(double)> f3 = Functor();
因此我们就可以吧三种不同类的函数放到同一个vector中,如下:
方法一:
vector<function<double(double)>> v = { f1, f2, f3 };
方法二:
vector<function<double(double)>> v = { f, [](double d)->double { return d / 4; }, Functor() };
因此我们就可以这样取调用它:
vector<function<double(double)>> v = { f, [](double d)->double { return d / 4; }, Functor() };double n = 3.3;
for (auto f : v)
{cout << f(n++) << endl;
}
有了function以后,我们就可以同一类型,解决实例化多份的问题,如下图,三类只实例化出一份。
#include <functional>
template<class F, class T>
T useF(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return f(x);
}
double f(double i)
{return i / 2;
}
struct Functor
{double operator()(double d){return d / 3;}
};
int main()
{// 函数名std::function<double(double)> func1 = f;cout << useF(func1, 11.11) << endl;// 函数对象std::function<double(double)> func2 = Functor();cout << useF(func2, 11.11) << endl;// lamber表达式std::function<double(double)> func3 = [](double d)->double { return d /4; };cout << useF(func3, 11.11) << endl;return 0;
}
(3)function应用
我们来通过一道习题展示他的应用:
https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/submissions/
这是我们之前写的代码,要判断多次运算符而且冗余:
class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> s;for (size_t i = 0; i < tokens.size(); i++){if (tokens[i] == "+" ||tokens[i] == "-" ||tokens[i] == "*" ||tokens[i] == "/" ){int right = s.top();s.pop();int left = s.top();s.pop();switch(tokens[i][0]){case '+':s.push(left + right);break;case '-':s.push(left - right);break;case '*':s.push(left * right);break;case '/':s.push(left / right);break;}}else{s.push(atoi(tokens[i].c_str()));}}return s.top();}
};
有了function之后我们就可以这样做~
class Solution {
public:int evalRPN(vector<string>& tokens) {map<string, function<int(int, int)>> cmdFuncMap ={{"+", [](int x, int y){return x + y;}},{"-", [](int x, int y){return x - y;}},{"*", [](int x, int y){return x * y;}},{"/", [](int x, int y){return x / y;}}};stack<int> st;// 运算数入栈,运算符运算for(auto& e : tokens){if (cmdFuncMap.count(e)){//运算int right = st.top();st.pop();int left = st.top();st.pop();st.push(cmdFuncMap[e](left, right));}else{st.push(stoi(e));}}return st.top();}
};
代码看起来是不是清晰很多呢~
2. bind
(1)bind语法
- 对于函数:
bind(函数名, placeholders::_x, placeholders::_x, ...)
- 对于静态成员函数:
bind(作用域::静态成员函数, placeholders::_x, placeholders::_x, ...)
,也可以写成:bind(作用域::&静态成员函数, placeholders::_x, placeholders::_x, ...)
- 对于普通成员函数:
bind(作用域::&普通成员函数, '&对象'或'匿名对象',placeholders::_x, placeholders::_x, ...)
(2)bind用处
bind(绑定)是什么呢?
简单来说就是传参的时候我们可以改变参数的顺序,以此达到我们想要的效果:
int Sub(int a, int b)
{return a - b;
}int main()
{function<int(int, int)> sub1 = bind(Sub, placeholders::_2, placeholders::_1);cout << sub1(10, 5);
}
他的原理是这样的:
传参的时候第一个函数会去匹配placeholder::_1
,第二个会去匹配_2,而bind却是按照参数的顺序绑定的,因此我们可以更加灵活调整传参数顺序。
如果有其他参数放到对应位置正常写即可,就像这样:
(3)对于成员函数
class SubType
{
public:static int sub(int a, int b){return a - b;}int ssub(int a, int b, int rate){return (a - b) * rate;}
};
对于静态成员函数是这样的:
这个&
可加可不加,建议加上。
对于普通成员变量:
第一个前必须加&
,后面可以匿名对象,也可以&对象。其实就是.
还是->
问题。
总结
C++11语法持续更新中,还有智能指针等章节在后续讲解中,谢谢大家支持!
相关文章:
C++11_2
文章目录 前言一、新的类功能——新的默认成员函数1. 编译器默认生成的移动构造与移动赋值2. 手动提供移动构造或移动赋值的影响 二、可变参数模板1. 多参数1. 可变参数模板的基础 2. 可变参数模板的展开(1)递归展开参数包(2)使用…...
HTML语义化与无障碍设计
HTML 语义化与无障碍设计:构建包容且高效的网页体验 引言 在我的前端开发学习旅程中,起初将 HTML 仅视为页面布局的工具,大量使用无语义的 <div> 和 <span>。直到在一篇技术博客当中了解到,作者在一次团队项目中&am…...
Ubuntu多用户VNC远程桌面环境搭建:从零开始的完整指南
引言: 在当今远程工作盛行的时代,搭建一个安全、高效的多用户远程桌面环境变得越来越重要。本文将为您提供一个从零开始的完整指南,教您如何在Ubuntu系统上搭建多用户VNC远程桌面环境。无论您是系统管理员、开发团队负责人,还是想要为家庭成员提供远程访问的技术爱好者,这…...
Electron 中引入MessageChannel 大大缩短不同渲染进程和 Webview 各组件 1o1的通信链路
背景 在 electron 开发中,也不可避免地遇到端到端的通信问题,Electron 已经内置一些通信 API,但是实际用下来会发现,在引入 Webview 之后,通信链路会很长,参考 利用本地 Express Web 服务解决复杂的 Elec…...
Vscode开发Vue项目NodeJs启动报错处理
文章目录 背景一、npm启动报错报错信息定位原因处理方案第一步、下载安装高版本 二、node 无法识别报错信息处理方案定位原因第一步、检测环境变量第二步、重新开启界面 背景 使用Vscode开发Vue项目,使用到NodeJs,记录出现的问题及处理方案,…...
AI agents系列之AI工作流和AI智能体对比
在人工智能(AI)快速发展的今天,理解AI工作流和AI智能体之间的区别对于有效利用这些技术至关重要。本文将深入探讨AI工作流的类型,解析AI智能体的概念,并重点比较二者的关键差异。 1. 智能体 vs 工作流 关于“智能体”的定义众说纷纭。有些客户将其视为完全自主的系统,能…...
如何恢复极狐GitLab?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 恢复极狐GitLab (BASIC SELF) 极狐GitLab 提供了一个命令行界面来恢复整个安装,足够灵活以满足您的需求。 恢复…...
基于X86/Nvidia+FPGA大模型具身智能机器人控制器解决方案,同时拥有算力与实时的便利
2025年成为人形机器人产业化元年,行业已突破早期实验室研发阶段,进入"场景验证量产爬坡"新周期,预计2031年具身智能市场规模有望突破万亿元。这一进程的背后,是硬件算力、实时控制、环境适应等底层技术的系统性突破——…...
MATLAB项目实战(一)
题目: 某公司有6个建筑工地要开工,每个工地的位置(用平面坐标系a,b表示,距离单位:km)及水泥日用量d(t)由下表给出.目前有两个临时料场位于A(5,1),B(2,7),日储…...
PyCharm Flask 使用 Tailwind CSS 配置
使用 Tailwind CSS 步骤 1:初始化项目 在 PyCharm 终端运行:npm init -y安装 Tailwind CSS:npm install -D tailwindcss postcss autoprefixer初始化 Tailwind 配置文件:npx tailwindcss init这会生成 tailwind.config.js。 步…...
Mybtis和Mybatis-Plus区别
MyBatis 和 MyBatis-Plus 是 Java 中常用的持久层框架,MyBatis-Plus 是在 MyBatis 基础上增强的工具包,让开发更便捷、高效。下面是两者主要的区别: ✅ 核心区别总结: 特性MyBatisMyBatis-Plus配置复杂度需要手写大量 XML 或注解…...
《Learning Langchain》阅读笔记2-基于 Gemini 的 Langchain PromptTemplate 实现方式
本文将使用Gemini实现《Learning Langchain》中的PromptTemplate 实现方式,替代书中的调用openai API,白嫖太香了! 调试步骤 我们首先还是先在本地调试是否可以调用Gemini API: import getpass import osif "GOOGLE_API_K…...
LVS+keepalived搭建高可用架构
背景:最近在搭建LVSkeepalived的高可用架构,中间遇到了一些坑比较让人头疼,此处重要就安装部署的步骤进行记录,特别是遇到坑进行说明,希望能对有需要的同学提供给帮助! 坑点1: 在部署LVSkeepalived并且使用…...
【天梯赛练习】L2-035 完全二叉树的层序遍历
后序遍历转层序遍历 后序遍历:左——右——根层序遍历:数组形式存储的完全二叉树的顺序遍历序列其实就正好是其层序遍历序列。 子树根若是 i d id id,左子树 i d ∗ 2 id*2 id∗2,右子树 2 ∗ i d 1 2*id1 2∗id1 所以就是dfs递…...
2025.4.20机器学习笔记:文献阅读
2025.4.20周报 题目信息摘要创新点网络架构实验生成性能对比预测性能对比 结论不足以及展望 题目信息 题目: A novel flood forecasting model based on TimeGAN for data-sparse basins期刊: Stochastic Environmental Research and Risk Assessment作…...
Leetcode 3359. 查找最大元素不超过 K 的有序子矩阵【Plus题】
1.题目基本信息 1.1.题目描述 给定一个大小为 m x n 的二维矩阵 grid。同时给定一个 非负整数 k。 返回满足下列条件的 grid 的子矩阵数量: 子矩阵中最大的元素 小于等于 k。 子矩阵的每一行都以 非递增 顺序排序。 矩阵的子矩阵 (x1, y1, x2, y2) 是通过选择…...
Redis面试——事务
一、Redis原子性是什么? (1)单个命令的原子性 原子性是指一组操作,要么全部执行成功,要么全部失败。Redis 中的单个命令是天然原子性的,因为 Redis 的命令执行采用单线程模型,同一时间只会执行…...
【远程管理绿联NAS】家庭云存储无公网IP解决方案:绿联NAS安装内网穿透
文章目录 前言1. 开启ssh服务2. ssh连接3. 安装cpolar内网穿透4. 配置绿联NAS公网地址 前言 大家好,今天要带给大家一个超级酷炫的技能——如何让绿联NAS秒变‘千里眼’,通过简单的几步操作就能轻松实现内网穿透。想象一下,无论你身处何地&a…...
AI写程序:用 AI 实现一个递归批量转化 GBK/GB2312 转 UTF-8 工具:轻松解决文本编码转换难题
用 AI 实现一个递归批量转化 GBK/GB2312 转 UTF-8 工具 在处理历史文件或与不同系统交互时,我们经常会遇到 GBK 或 GB2312 编码的文本文件。虽然现在 UTF-8 是主流,但手动转换这些旧编码文件既繁琐又容易出错。为了解决这个问题,我开发了一个…...
首席人工智能官(Chief Artificial Intelligence Officer,CAIO)的详细解析
以下是**首席人工智能官(Chief Artificial Intelligence Officer,CAIO)**的详细解析: 1. 职责与核心职能 制定AI战略 制定公司AI技术的长期战略,明确AI在业务中的应用场景和优先级,推动AI与核心业务的深度…...
uview1.0 tabs组件放到u-popup中在微信小程序中滑块样式错乱
解决思路 重新计算布局信息:在弹窗显示后重新调用 init 方法来计算组件的布局信息。使用 nextTick:保证在视图更新之后再进行布局信息的计算。 <u-tabs ref"tabsRef" ></u-tabs> makeClick(){this.makeShowtruethis.$nextTick…...
私人笔记:动手学大模型应用开发llm-universe项目环境创建
项目代码:datawhalechina/llm-universe: 本项目是一个面向小白开发者的大模型应用开发教程,在线阅读地址:https://datawhalechina.github.io/llm-universe/ 项目书:动手学大模型应用开发 一、初始化项目 uv init llm-universe-te…...
基于Django框架的图书索引智能排序系统设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
摘要 时代在飞速进步,每个行业都在努力发展现在先进技术,通过这些先进的技术来提高自己的水平和优势,图书管理系统当然不能排除在外。图书索引智能排序系统是在实际应用和软件工程的开发原理之上,运用Python语言以及Django框架进…...
网络类型学习
网络类型的分类依据-----基于二层(数据链路层)使用的协议不同而导致数据包的封装方式不同,工作方式也不同。 OSPF协议根据链路层协议类型将网络分为四种类型:广播型网络(BMA)、非广播多路访问(…...
ubuntu24.04离线安装deb格式的mysql-community-8.4.4
1,下载解压 参考: https://blog.csdn.net/2202_76101487/article/details/145967039 下载: wget https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-server_8.4.4-1ubuntu24.04_amd64.deb-bundle.tar 建议个目录mysql8然后把安装包移过去&…...
电控---printf重定向输出
在嵌入式系统开发中,printf 重定向输出是将标准输出(stdout)从默认设备(如主机终端)重新映射到嵌入式设备的特定硬件接口(如串口、LCD、USB等)的过程。 一、核心原理:标准IO库的底层…...
uniapp使用createSelectorQuery,boundingClientRect获取宽度和高度不准确的可用的解决方案
场景展示: uniapp使用createSelectorQuery,boundingClientRect获取宽度和高度不准确的可用的解决方案,正常来说,使用下面的代码是可以正确获得宽高的,但是里面含有图片,在图片没有加载完的情况下,我们可以…...
DSO:牛津大学推出的物理一致性3D模型优化框架
在数字内容创作和制造领域,将2D图像转换为高质量、物理上稳定的3D模型一直是一个挑战。传统的3D建模方法往往需要大量的手动调整以确保生成的物体不仅美观而且符合物理定律,能够在现实世界中稳定存在。牛津大学近期推出了一款名为DSO(Direct Sparse Odometry)的项目,它不仅…...
Delphi Ini文件对UTF8支持不爽的极简替代方案
如题,没太多废话,直接复制走即可。 unit uConfig;interfaceuses classes, Sysutils;typeTConfig class privateFFileName: String;FConfig:TStringList; protectedpublicconstructor Create(ConfigFile:String);destructor Destroy;property FileName…...
Windows平台使用Docker部署Neo4j
✅ Docker 安装 Neo4j 前提条件:安装docker 打开docker desktop docker run \--name neo4j \-p7474:7474 -p7687:7687 \-d \-e NEO4J_AUTHneo4j/password123 \neo4j:5默认用户名是 neo4j,密码是你设置的,比如上面是 password123 ✅用 Pyt…...
FreeRTOS二值信号量详解与实战教程
FreeRTOS二值信号量详解与实战教程 📚 作者推荐:想系统学习FreeRTOS嵌入式开发?请访问我的FreeRTOS开源学习库,内含从入门到精通的完整教程和实例代码! 1. 二值信号量核心概念解析 二值信号量(Binary Semaphore)是Fre…...
数据结构与算法[零基础]---6.算法概况
六、算法概述 (一)算法的概述 任何解决问题的过程都是由一定的步骤组成的,把解决问题的方法和有限的步骤称作算法 (二)算法的基本特征 1.有穷性 算法必须在执行有限个操作之后终止,且每一步都可在有限时间内完成。 2.确定性 算…...
STL简介(了解)
1.什么是STL STL(standard template libaray)是标准模板库,它是C标准库的一部分。C标准库中还有一些其它东西,比如之前用的IO流。它主要是数据结构和算法的库。 2.STL的版本 C3.0出来后就有了模板,此时大家已经深受没有数据结构算法库的痛苦…...
使用 Oh My Posh 自定义 PowerShell 提示符
使用 Oh My Posh 自定义 PowerShell 提示符 由于ai生图,ai视频这方面mac太差了,买N卡,转windows了,这里也记录一下 PowerShell 配置Oh My Posh 先上效果图 一、下载 PowerShell7 默认的 PowerShell5 太差了,下载地…...
4月17号
//1.编码 String str "ai你哟"; byte[] bytes1 str.getBytes(); System.out.println(Arrays.toString(bytes1)); byte[] bytes2 str.getBytes(charsetName: "GBK"); System.out.println(Arrays.toString(bytes2));//2.解码 String str2 new String(byt…...
react-native搭建开发环境过程记录
主要参考:官网的教程 https://reactnative.cn/docs/environment-setup 环境介绍:macos ios npm - 已装node18 - 已装,通过nvm进行版本控制Homebrew- 已装yarn - 已装ruby - macos系统自带的2.2版本。watchman - 正常安装Xcode - 正常安装和…...
自然语言处理(NLP)技术。
自然语言处理(NLP)技术可以应用于多个领域,以下是一些示例: 情感分析:NLP可以用来分析文本中包含的情感,帮助企业了解用户对他们产品或服务的感受。例如,社交媒体平台可以利用情感分析技术来监测…...
Ubuntu 安装WPS Office
文章目录 Ubuntu 安装WPS Office下载安装文件安装WPS问题1.下载缺失字体文件2.安装缺失字体 Ubuntu 安装WPS Office 下载安装文件 需要到 WPS官网 下载最新软件,比如wps-office_12.1.0.17900_amd64.deb 安装WPS 执行命令进行安装 sudo dpkg -i wps-office_12.1…...
【WPF】 自定义控件的自定义属性
文章目录 前言一、自定义控件部分二、在页面中使用总结 前言 在一个页面,重复用到同一个自定义控件时,该如何对控件分别进行数据绑定呢?这时候可以赋予控件一个自定义的属性,来完成此操作。 一、自定义控件部分 为自定以控件设置…...
Unity URP Moblie AR示例工程,真机打包出来,没阴影
效果: unity ar示例演示 现象: 真机打包测试私活没有阴影 Unity版本:2022.3.4f1c1 分析原因: Prefab :ARFeatheredPlane中也有材质,一个用于环境遮挡,一个用于阴影接受。 按理说有啊。 urp …...
如何删除word中的长横线(由三个减号---自动生成/由三个等号===自动生成/由三个###自动生成)_word三个减号回车的横线怎么删除-CSDN博客
方法1、选中前后行ctrlX剪切掉 方法2:如果文件中没有表格就非常简单,直接CtrlA全选整个文档,然后在表格边框里面选择“无框线”OK,如果有表格的话,就从横线的下行开始向上随意选取一部分,同样在表格边框中选…...
函数返回const引用,使用const修饰变量接收
函数返回const引用,使用const修饰变量接收 1、背景 想获取红绿灯时长数组并添加新的值。有个函数是返回红绿灯时长数组的。函数返回类型为const引用,我使用无修饰的变量接收。但是感觉有些问题,并且之前看到const变量变成非const还需要使用…...
在激烈竞争下B端HMI设计怎样打造独特用户体验?
在当今数字化高度发展的时代,B 端市场竞争愈发激烈。对于 B 端 HMI(人机界面)设计而言,打造独特的用户体验已成为在竞争中脱颖而出的关键因素。B 端用户在复杂的工作场景中,对 HMI 设计有着独特的需求和期望࿰…...
数理逻辑(Mathematical Logic)综论与跨学科应用
李升伟 整理 数理逻辑(Mathematical Logic)是现代逻辑学与数学交叉的核心学科,以严格的数学方法研究逻辑推理的形式与规律。其发展深刻影响了数学基础、计算机科学、语言哲学等领域。以下从多个维度综论数理逻辑: 1. 核心分支 命…...
4.17---实现商铺和缓存与数据库双写一致以及宕机处理
实现商铺和缓存与数据库双写一致(以及强双写一致策略) redis点评项目采用的是延时双删策略 双删: 我们更新完数据库之后删除缓存,这样即使有线程并发进来查询,会发现缓存中没有数据,从而会去mysql中查找…...
qt与html通信
**Cef视图(CefView)**是指在使用Chromium Embedded Framework(CEF)时,嵌入到应用程序中的浏览器视图。CEF是一个开源项目,它基于Google的Chromium浏览器,允许开发者将Web浏览器功能嵌入到自己的…...
【从零实现高并发内存池】thread cache、central cache 和 page cache 回收策略详解
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
算法5-16 对二进制字符串解码
输入样例: 5 a 4 b 3 c 2 w 1 z 1 100001110101101101100111输出样例: baaacabwbzc ac代码: #include<iostream> #include<queue> #include<map> using namespace std; const int N10010; int idx; int a[N][2]; char b…...
[MySQL数据库] InnoDB存储引擎(三): 内存结构详解
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
TDengine 存储引擎剖析:数据文件与索引设计(一)
TDengine 存储引擎简介 在物联网、工业互联网等快速发展的今天,时间序列数据呈爆发式增长。这些数据具有产生频率高、依赖采集时间、测点多信息量大等特点,对数据存储和处理提出了极高要求。TDengine 作为一款高性能、分布式、支持 SQL 的时序数据库&am…...