C++提高编程——模板

本专栏记录C++学习过程包括C++基础以及数据结构和算法,其中第一部分计划时间一个月,主要跟着黑马视频教程,学习路线如下,不定时更新,欢迎关注
当前章节处于:
---------第1阶段-C++基础入门
---------第2阶段实战-通讯录管理系统,
---------第3阶段-C++核心编程,
---------第4阶段实战-基于多态的企业职工系统
=====>第5阶段-C++提高编程
---------第6阶段实战-基于STL泛化编程的演讲比赛
---------第7阶段-C++实战项目机房预约管理系统

文章目录

  • 一、概念
  • 二、函数模板
    • 2.1 基本语法
    • 2.2 注意事项
    • 2.3 普通函数和模板函数的区别
    • 2.4 普通函数和函数模板调用规则
    • 2.5 模板的局限性
  • 三、类模板
    • 3.1 基本语法
    • 3.2 类模板中成员函数创建时机
    • 3.3 类模板对象做函数参数
    • 3.4 类模板与继承
    • 3.5 类模板成员函数类外实现
    • 3.6 类模板分文件编写
    • 3.7 类模板和友元

一、概念

模板就是建立通用的模具,大大提高复用性。模板不可以直接使用,只是一个框架,并且模板的通用并不是万能的。使用模板的目的是提高复用性,将类型参数化。

二、函数模板

2.1 基本语法

template
函数声明或定义

  • template:声明创建模板
  • typename:表明其后面的符号是一种数据类型,可以用class代替
  • T:通用的数据类型,名称可以替换,通常为大写字母,可以定义多个
#include <iostream>
using namespace std;// 定义一个交换的函数模板
template <typename T>
void Myswap(T& a, T& b) {T temp = a;a = b;b = temp;
}void test() {int a = 10;int b = 20;char c = 'c';char d = 'd';// 1. 自动推导型Myswap(a, b);cout << "a=" << a << endl;cout << "b=" << b << endl;// 2. 显示推导型Myswap<char>(c, d);cout << "c=" << c << endl;cout << "d=" << d << endl;}int main() {test();system("pause");return 0;}
a=20
b=10
c=d
d=c
请按任意键继续. . .

2.2 注意事项

  1. 自动类型推导,必须推导出一致的数据类型,才可以使用
  2. 模板必须要确定出T的数据类型,才可以使用
    第一个好理解,比如上面的Myswap,如果传入的两个实参类型不一致时,则会导致推导出来的T的类型不一致,则无法使用。下面对于第二点进行代码讲解:
#include <iostream>
using namespace std;// 定义模板
template <class T>
void func() {cout << "调用函数模板" << endl;
}void test() {// func(); // 错误func<int>(); // 正确
}int main() {test();system("pause");return 0;}
调用函数模板
请按任意键继续. . .

实战案例

  • 利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序
  • 排序规则从大到小,排序算法为选择排序
  • 分别利用char数组和int数组进行排序
#include <iostream>
using namespace std;// 排序函数模板
template<class T>
void func(T arr[],int length) {// 选择排序for (int i = 0; i < length; i++) {int max = i; // 认为当前的是最大值for (int j = i+1; j < length; j++) {if (arr[max] < arr[j]) {max = j;}}// 调换两个值T temp = arr[i];arr[i] = arr[max];arr[max] = temp;}
}// 打印函数模板
template <class T>
void printArr(T arr[],int length) {for (int i = 0; i < length; i++) {cout << arr[i] << " ";}cout << endl;
}// 测试整型
void test01() {int arr[10] = { 1,4,3,2,6,7,5,9,8,0 };func(arr, 10);printArr(arr, 10);
}
void test02() {char arr[] = "acbdfeg";int length = sizeof(arr) / sizeof(arr[0]);func(arr,length);printArr(arr, length);
}
int main() {test01();test02();system("pause");return 0;}
9 8 7 6 5 4 3 2 1 0
g f e d c b a
请按任意键继续. . .

2.3 普通函数和模板函数的区别

  • 普通函数调用时可以发生自动类型转化(隐式类型转化)
  • 函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
  • 如果利用显示指定类型的方式,可以发生隐式类型转化
#include <iostream>
using namespace std;// 定义一个函数模板
template<class T>
T func1(T a, T b) {cout << "调用的是函数模板!" << endl;return a + b;
}// 定义一个普通函数
int func2(int a,int b) {cout << "调用的是普通函数!" << endl;return a + b;
}// 测试案例
void test() {int a = 10;int b = 20;char c = 'c';cout << func1(a, b) << endl;cout << func2(a, c) << endl;//cout << func1(a, c) << endl;// 报错cout << func1<int>(a, c) << endl;// 不报错
}
int main() {test();system("pause");return 0;}
调用的是函数模板!
30
调用的是普通函数!
109
调用的是函数模板!
109
请按任意键继续. . .

2.4 普通函数和函数模板调用规则

  1. 如果函数模板和普通函数都可以实现,优先调用普通函数
  2. 可以通过空模板参数列表来强制调用函数模板
  3. 函数模板也可以发生重载
  4. 如果函数模板可以更好的匹配,优先调用函数模板

下面通过具体代码进行逐个讲解

#include <iostream>
using namespace std;
// 定义普通函数
void MyPrint(int a,int b) {cout << "调用的是普通函数" << endl;
}// 定义模板函数
template<class T>
void MyPrint(T a, T b) {cout << "调用的是模板函数" << endl;
}
// 重载模板函数
template<typename T>
void MyPrint(T a, T b, T c)
{cout << "调用重载的模板函数" << endl;
}int main() {// 1. 如果函数模板和普通函数都可以实现,优先调用普通函数int a = 10; int b = 20;MyPrint(a, b);// 2.可以通过空模板参数列表来强制调用函数模板MyPrint<>(a, b);// 3.函数模板也可以发生重载MyPrint(a, b, 30);// 4.如果函数模板可以产生更好的匹配,优先调用函数模板char c1 = 'a';char c2 = 'b';MyPrint(c1, c2);system("pause");return 0;}
调用的是普通函数
调用的是模板函数
调用重载的模板函数
调用的是模板函数
请按任意键继续. . .

总结:如果提供了函数模板,最好就不要再提供对应的普通函数,否则容易出现二义性。

2.5 模板的局限性

如果T的数据类型传入的是像Person这样的自定义数据类型,也无法正常进行比较运算,C++为了解决这种问题,提供模板的重载,为这些特定类型提供具体化模板。

#include <iostream>
using namespace std;
class Person {
public:Person(string name,int age) {m_Name = name;m_Age = age;}string m_Name;int m_Age;
};
// 普通函数模板
template<class T>
bool myCompare(T& a, T& b) {return a == b;
}
// 具体化 优先于常规模板
template<> bool myCompare(Person& p1, Person& p2) {if (p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age){return true;}else{return false;}
}void test() {Person p1("Tom", 10);Person p2("Tom", 10);cout << myCompare(p1, p2) << endl;
}
int main() {test();system("pause");return 0;}
1
请按任意键继续. . .

利用具体化的模板,可以解决自定义类型的通用化,学习模板并不是为了写模板,而是再STL中能够运用系统提供的模板。

三、类模板

类似于函数模板,类有也对应的类模板,类模板的作用是建立一个通用类,类中的成员,数据类型可以不具体制定,用一个虚拟的类型来代表,语法为
template<typename T>

  • template — 声明创建模板
  • typename — 表面其后面的符号是一种数据类型,可以用class代替
  • T — 通用的数据类型,名称可以替换,通常为大写字母

3.1 基本语法

#include <iostream>
using namespace std;// 定义一个交换的函数模板
template <typename T>
void Myswap(T& a, T& b) {T temp = a;a = b;b = temp;
}void test() {int a = 10;int b = 20;char c = 'c';char d = 'd';// 1. 自动推导型Myswap(a, b);cout << "a=" << a << endl;cout << "b=" << b << endl;// 2. 显示推导型Myswap<char>(c, d);cout << "c=" << c << endl;cout << "d=" << d << endl;}int main() {test();system("pause");return 0;}
姓名:孙悟空  年龄:999
姓名:猪八戒  年龄:888
请按任意键继续. . .

3.2 类模板中成员函数创建时机

类模板中成员函数和普通类中成员函数创建时机是有区别的:

  • 普通类中的成员函数一开始就可以创建
  • 类模板中的成员函数再调用时才创建
#include <iostream>
using namespace std;
class Person1
{
public:void showPerson1(){cout << "Person1 show" << endl;}
};class Person2
{
public:void showPerson2(){cout << "Person2 show" << endl;}
};
// 定义类模板
template<class T>
class MyClass
{
public:T obj;//类模板中的成员函数,并不是一开始就创建的,而是在模板调用时再生成void fun1() { obj.showPerson1(); }void fun2() { obj.showPerson2(); }};
void test01()
{MyClass<Person1> m;m.fun1();//m.fun2();//编译会出错,说明函数调用才会去创建成员函数
}
int main() {test01();system("pause");return 0;}
Person1 show
请按任意键继续. . .

3.3 类模板对象做函数参数

类模板实例化出的对象,向函数传参的方式

一共有三种传入方式:

  1. 指定传入的形式:直接显示对象的数据类型,这是用的最多的一种方式
  2. 参数模板化:将对象中的参数变为模板进行传递
  3. 整个类模板化:将这个对象类型,模板化进行传递

下面用代码进行讲解:

#include <iostream>
using namespace std;
// 创建一个类模板
template<class NameType, class AgeType = int> // 默认参数为int
class Person
{
public:Person(NameType name, AgeType age){this->mName = name;this->mAge = age;}void showPerson(){cout << "name: " << this->mName << " age: " << this->mAge << endl;}
public:NameType mName;AgeType mAge;
};
//1、指定传入的类型,最常用的一种方式
void printPerson1(Person<string, int>& p)
{p.showPerson();
}
void test01()
{Person <string, int >p("孙悟空", 100);printPerson1(p);
}//2、参数模板化
template <class T1, class T2>
void printPerson2(Person<T1, T2>& p)
{p.showPerson();cout << "T1的类型为: " << typeid(T1).name() << endl;cout << "T2的类型为: " << typeid(T2).name() << endl;
}
void test02()
{Person <string, int >p("猪八戒", 90);printPerson2(p);
}//3、整个类模板化
template<class T>
void printPerson3(T& p)
{cout << "T的类型为: " << typeid(T).name() << endl;p.showPerson();}
void test03()
{Person <string, int >p("唐僧", 30);printPerson3(p);
}int main() {test01();test02();test03();system("pause");return 0;
}
int main() {system("pause");return 0;}
name: 孙悟空 age: 100
name: 猪八戒 age: 90
T1的类型为: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
T2的类型为: int
T的类型为: class Person<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int>
name: 唐僧 age: 30
请按任意键继续. . .

3.4 类模板与继承

当类模板碰到继承时,需要注意一下几点:

  • 当子类继承的父类是一个类模板时,子类在声明的时候,要制定出父类中T的类型
  • 如果不指定,编译器无法给子类分配内存
  • 如果想灵活指定出父类中T的类型,子类也需变成类模板
#include <iostream>
// 父类类模板
using namespace std;
template<class T>
class Base
{T m;
};// 子类继承父类
// class Son :public Base {}; // 错误,必须要确定父类中的T
class Son :public Base<int> {};
void test01()
{Son c;// 实例化对象
}
template<class T2>
class Son2 :public Base<T2>
{
public:Son2(){cout << typeid(T2).name() << endl;}
};void test02()
{Son2<char> child1;
}
int main() {test01();test02();system("pause");return 0;}
char
请按任意键继续. . .

3.5 类模板成员函数类外实现

#include <iostream>
using namespace std;template<class NameType, class AgeType = int> // 默认参数为int
class Person
{
public:Person(NameType name, AgeType age);void showPerson();
public:NameType mName;AgeType mAge;
};
// 构造函数 类外实现
template<class NameType, class AgeType>
Person<NameType, AgeType>::Person(NameType name, AgeType age)
{this->mName = name;this->mAge = age;
}
// 成员函数类外实现
template<class NameType, class AgeType>
void Person<NameType, AgeType>::showPerson()
{cout << "name: " << this->mName << " age: " << this->mAge << endl;
}int main() {Person<string, int> p("张三", 13);p.showPerson();system("pause");return 0;}
name: 张三 age: 13
请按任意键继续. . .

3.6 类模板分文件编写

由于类模板中成员函数创建时机是在调用阶段,导致分文件编写时连接不到,有两种解决方案:

  • 直接包含cpp源文件
  • 将声明和实现写到同一个文件中,并更改后缀名为.hpp (更常用)

Person.hpp

#pragma once
#include <iostream>
using namespace std;template<class NameType, class AgeType = int> // 默认参数为int
class Person
{
public:Person(NameType name, AgeType age);void showPerson();
public:NameType mName;AgeType mAge;
};
// 构造函数 类外实现
template<class NameType, class AgeType>
Person<NameType, AgeType>::Person(NameType name, AgeType age)
{this->mName = name;this->mAge = age;
}
// 成员函数类外实现
template<class NameType, class AgeType>
void Person<NameType, AgeType>::showPerson()
{cout << "name: " << this->mName << " age: " << this->mAge << endl;
}

类模板分文件编写.cpp

#include <iostream>
using namespace std;#include "Person.hpp"int main() {Person<string, int> p("张三", 13);p.showPerson();system("pause");return 0;}
name: 张三 age: 13
请按任意键继续. . .

3.7 类模板和友元

#include <iostream>
using namespace std;
template <class T1,class T2>
class Person;// 2. 全局函数类外实现
template <class T1, class T2>
void showPerson(Person<T1, T2> p) {cout << "姓名:" << p.m_Name << "  年龄:" << p.m_Age << endl;
}template <class T1, class T2>
class Person {// 1. 全局函数类内实现// 加上friend变为全局函数,如果不加的话就是成员函数//friend void showPerson(Person<T1,T2> p) {//	cout << "姓名:" << p.m_Name << "  年龄:" << p.m_Age << endl;//}// 如果全局函数是类外实现,需要让编译器提前知道这个函数存在friend void showPerson<>(Person<T1, T2> p);
public:Person(T1 name, T2 age) {this->m_Name = name;this->m_Age = age;}
private:T1 m_Name;T2 m_Age;
};int main() {Person<string, int> p("Tom", 12);showPerson(p);system("pause");return 0;}
姓名:Tom  年龄:12
请按任意键继续. . .

实战案例
实现一个通用的数组类

  1. 可以对内置数据类型以及自定义数据类型的数据进行存储
  2. 将数组中的数据存储到堆区
  3. 构造函数中可以川入数组的容量
  4. 提供对应的拷贝构造函数以及operator=防止浅拷贝问题
  5. 提供尾插法和尾删法对数组中的数据进行增加和删除
  6. 可以通过下标的方式访问数组中的元素
  7. 可以获取数组中当前元素个数和数组的容量

main.cpp

#include <iostream>
using namespace std;
#include "MyArray.hpp"
class Person {
public:Person() {}Person(string name, int age) {m_name = name;m_age = age;}string getName() {return m_name;}int getAge() {return m_age;}
private:string m_name;int m_age=0;
};void showPerson(Myarray<Person> array,int num) {for (int i = 0; i < num; i++) {cout << "姓名:" << array[i].getName() << "   年龄:"<<array[i].getAge()<<endl;}
}
void showInt(Myarray<int> arr, int num) {for (int i = 0; i < num; i++) {cout << arr[i] << " ";}cout << endl;
}void test() {Myarray<int> arr(10);for (int i = 0; i < 10; i++) {arr.insert_Back(i);}showInt(arr, 10);//Myarray<int> arr2(arr);//Myarray<int> arr3(20);//arr3 = arr;//cout <<"arr3的容量为"<< arr3.get_Mcap() << endl;Myarray<Person> PersonArr(2);Person p1("张三", 12);Person p2("李四", 21);PersonArr.insert_Back(p1);PersonArr.insert_Back(p2);showPerson(PersonArr,2);
}
int main() {test();system("pause");return 0;}

MyArray.hpp

#pragma once
#include <iostream>
using namespace std;template <class T>
class Myarray {
public:// 有参构造Myarray(int cap) {cout << "调用有参构造函数" << endl;//cout << "hello" << endl;this->m_cap = cap;this->pArray = new T[this->m_cap]; // 在堆区开辟this->size = 0;}// 拷贝构造Myarray(Myarray& arr) {//cout << "调用拷贝构造函数" << endl;this->size = arr.size;this->m_cap = arr.m_cap;this->pArray = new T[arr.m_cap];// 将arr中的数据拿过来for (int i = 0; i < arr.size; i++) {this->pArray[i] = arr.pArray[i];}}// 析构函数~Myarray() {if (this->pArray!= NULL) {cout << "调用析构函数" << endl;this->m_cap = 0;this->size = 0;// pArray是个数组  删除时要注意格式delete[] pArray;pArray = NULL;//cout << "删除完成" << endl;}}// 重载=操作运算符Myarray& operator=(const Myarray& arr) {//cout << "调用operator=函数" << endl;// 先判断原来栈区是否有数据if (this->pArray != NULL) {delete[] pArray;pArray = NULL;this->m_cap = 0;this->size = 0;}this->m_cap = arr.m_cap;this->size = arr.size;this->pArray = new T[arr.m_cap];return *this;}// 重载[]操作运算符T& operator[](int index) {return pArray[index];}// 获取数组容量int get_Mcap() {return this->m_cap;}// 获取数组大小int get_Size() {return this->size;}// 获取// 尾插法void insert_Back(T value) {// 判断还有无空间if (this->size == this->m_cap) {cout << "达到插入上限!" << endl;return ;}this->pArray[this->size] = value;this->size++;//return *this;}// 尾删法void pop_Back() {// 判断是否为0if (this->size == 0) {cout << "已达删除上限!" << endl;return;}this->size--;}// 通过下标方式访问元素T& get_index(int index) {if (index<0 || index>this.size) {cout << "索引有无!" << endl;return;}return this->pArray[index];}
private:T* pArray; // 头指针int m_cap; // 容量int size; // 大小
};
调用有参构造函数
0 1 2 3 4 5 6 7 8 9
调用析构函数
调用有参构造函数
姓名:张三   年龄:12
姓名:李四   年龄:21
调用析构函数
调用析构函数
调用析构函数
请按任意键继续. . .

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/640597.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

samba服务搭建,并将共享目录映射到windows

系统版本&#xff1a;centos7 1、centos 安装samba yum -y install samba 2、查看安装信息 rpm -qa |grep samba 3、设置开机自启动 systemctl enable smb.service systemctl enable nmb.service 4、设置samba服务器配置文件 sudo vi /etc/samba/smb.conf 注意&#…

CentOS 系统创建网卡bond0

很多时候在机房运维的过程中&#xff0c;我们会遇到客户要求的建立网卡光口的bond0设置&#xff0c;通俗点说就是将两个光口合并为一个口进行链接设置。创建这个设置是有两种设置&#xff0c;一是在安装系统的过程中对bond0进行创建设置&#xff0c;另一种就是通过系统里面对网…

Mac使用adb调试安卓手机

0x00 背景 最近windows电脑休息&#xff0c;用mac办公比较多&#xff0c;手机用时间长了&#xff0c;不太灵光&#xff0c;准备修理一番。于是要用mac调试下android手机。配置略显麻烦&#xff0c;网上的步骤多参差不齐。估计是入门步骤&#xff0c;大佬们也懒得写的太细。于是…

14.1.1 ASP简介

14.1.1 ASP简介 ASP 的全称是Active Server Pages&#xff0c;是由鼎鼎大名的Microsoft(微软)公司开发的服务器端语言。有强大的微软做后盾&#xff0c;ASP在众多的服务器端语言中长久不衰&#xff0c;至今仍有成千上万的网站在使用ASP语言。ASP 内置于IIS中&#xff0c;只要安…

【趣味题-07】20240121他的第一周工资(精准推测工资)

背景需求 设计过程&#xff1a; AI写了很多的答案&#xff0c;但是都不正确 于是我去查看了网上的正确答案——47.41美元 此外&#xff0c;题目的0.99涉及了浮点数&#xff0c;非整数&#xff0c;无法range遍历 最后终于有一个答案正确的代码 通过反复测试&#xff0c;终于写出…

详细版Git的下载安装与配置(Windows)

一、git的下载 Git是一个非常好用的版本控制工具。下载地址如下&#xff1a;Git - Downloads。建议使用国内浏览器下载&#xff0c;因为不用翻墙&#xff0c;速度快。 当你用浏览器去访问上面的地址后&#xff0c;下载页面会自动识别你的电脑系统&#xff0c;如下 点击&#…

NVMe TCG安全数据存储简介

NVMe&#xff08;非易失性内存主机控制器接口规范&#xff09;与TCG&#xff08;可信计算组&#xff09;的集成主要体现在数据安全、固件验证和硬件信任根等方面&#xff0c;以确保存储设备的数据保护能力和安全性。 TCG Opal定义了一套针对自加密硬盘&#xff08;SED, Self-En…

python操作word-样式

字体 引入 from docx.shared import Pt, Inches, RGBColor 加粗 # 加粗1 p1.add_run(这是内容1.1_加粗\n).font.bold True # 加粗2 p1 doc1.add_paragraph(这是段落1&#xff1a;\n) p1.runs[0].font.bold True 斜体 p1.add_run(这是内容1.2_斜体\n).font.italic True …

python蓝桥杯备考——字符串小知识点

python蓝桥杯备考——字符串小知识点 一、 问题解释&#xff1a; .join(str(k) for k in sorted(set(l)))含义和用法二、练习题目&#xff1a;完数的判断补充知识点&#xff1a; 一、 问题解释&#xff1a;’ .join(str(k) for k in sorted(set(l)))含义和用法 print(i, its f…

找不到msvcr100dll或msvcr100dll丢失怎么办,5种靠谱的解决方法分享

MSVCR100.dll文件的丢失可能会引发一系列系统运行和应用程序功能上的问题。作为Microsoft Visual C运行库中的一个关键动态链接库文件&#xff0c;它的缺失会导致依赖于此文件的软件无法正常启动或执行预期功能。具体表现可能包括但不限于&#xff1a;应用程序崩溃、闪退&#…

Python基础之异常处理

程序在运行过程中&#xff0c;难免会遇到错误&#xff0c;有的是编写人员疏忽造成的语法错误&#xff0c;有的是程序内部隐含逻辑问题造成的数据错误&#xff0c;还有的是程序运行时与系统的规则冲突造成的系统错误&#xff0c;等等。如果出错就不会执行出错语句后面的代码&…

Ubutu下的Shell操作

前言 在学习Ubuntu系统时&#xff0c;Shell操作是必不可少的知识。本篇文章是记录我学习Linux系统时&#xff0c;Ubutu下的Shell操作&#xff0c;希望我的分享对大家有所帮助&#xff01; 目录 前言 一、什么时是Shell 二、Shell的基本操作 三、常用的Shell命令 1、目录信…

GIS项目实战06:超详细Node.js安装及系统环境配置

简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境&#xff0c;基于 Google 的 V8 引擎&#xff0c;V8 引擎执行 Javascript 的速度非常快&#xff0c;性能…

一区优化直接写:KOA-CNN-BiLSTM-Attention开普勒优化卷积、长短期记忆网络融合注意力机制的多变量回归预测程序!

适用平台&#xff1a;Matlab 2023版及以上 KOA开普勒优化算法&#xff0c;于2023年5月发表在SCI、中科院1区Top顶级期刊《Knowledge-Based Systems》上。 该算法提出时间很短&#xff0c;目前还没有套用这个算法的文献。 同样的&#xff0c;我们利用该新鲜出炉的算法对我们的…

【好用的AI工具Kimi Chat】帮助提高面试效率

一、背景 年前裁员潮&#xff0c;不少人离职找工作&#xff0c;以及年后金三银四&#xff0c;也是求职高峰期。如何更高效的复习技术知识&#xff0c;以及特别是横纵向比对有总结性的问题。本文以面试【测试开发】的岗位为例&#xff0c;对面试题进行拓展&#xff0c;让AI帮助…

从 Vscode 中远程连接 WSL 服务器:可以本地操作虚拟机

从 Vscode 中远程连接 WSL 服务器&#xff1a;可以本地操作虚拟机 1.下载 Vscode Visual Studio Code - Code Editing. Redefined 2.搜索框中输入>wsl&#xff0c;点击 WSL&#xff1a;Connect to WSL using Distro... 3.点击下载好的Ubuntu&#xff0c;当左下角出现图片同…

U-Boot 中使用 nfs 命令加载文件报错指南

目录 问题一问题描述错误原因解决方案 问题二问题描述解决方案 更多内容 在嵌入式 Linux 开发中&#xff0c;我们经常使用 nfs 命令加载服务端的共享文件或者挂载文件系统。关于服务端 NFS 服务的搭建可以参考基于 NFS 的文件共享实现。 U-Boot 也支持了 nfs 命令&#xff0c;…

RabbitMQ数据隔离

1、新建用户 2、登录用户&#xff0c;设置虚拟主机 登录用户只能操作自己的虚拟主机&#xff0c;交换机等&#xff0c;不能操作其他人的&#xff01;&#xff01;&#xff01;

二维码地址门牌管理系统:登记管理新时代

文章目录 前言一、轻松登记&#xff0c;一扫即通二、智能化登记&#xff0c;优势明显三、政府支持与推广四、智能化管理未来展望 前言 二维码门牌管理系统的上线&#xff0c;为市民带来了便捷。系统不仅提升了登记效率&#xff0c;更保障了个人信息安全&#xff0c;成为城市管…

【Leetcode】2171. 拿出最少数目的魔法豆

文章目录 题目思路代码 题目 2171. 拿出最少数目的魔法豆 给定一个 正整数 数组 beans &#xff0c;其中每个整数表示一个袋子里装的魔法豆的数目。 请你从每个袋子中 拿出 一些豆子&#xff08;也可以 不拿出&#xff09;&#xff0c;使得剩下的 非空 袋子中&#xff08;即 至…