8、操作符重载
友元
- 可以通过friend关键字,把一个全局函数、另一个类的成员函数或者另一个类整体,声明为授权类的友元
- 友元拥有访问授权类任何非公有成员的特权
- 友元声明可以出现在授权类的公有、私有或者保护等任何区域且不受访问控制限定符的约束
- 友元不是成员,其作用域并不隶属于授权类,也不拥有授权类类型的this指针。
操作符标记和操作符函数
双目操作符表达式
L#R
成员函数形式:L.operator#(R)
- 左操作数是调用对象,右操作数是参数对象
全局函数形式:operator#(L,R)
- 左操作数是第一个参数,右操作数是第二个参数
单目操作符表达式
#O/O#
- 成员函数形式:O.operator#()
- 全局函数形式:operator#(O)
三目操作符表达式: F#S#T
三目操作符无法重载
经典双目操作符
运算类双目操作符:+、-、*、/等
- 左右操作数均可以为非常左值、常左值或右值
- 表达式的结果为右值
// 运算类双目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}// 成员形式操作符函数
// Human operator+(const Human& r) const {
// return Human(this->m_age+r.m_age, (this->m_name+"+"+r.m_name).c_str());
// }
private:int m_age;string m_name;friend Human operator+(const Human& l,const Human& r); // 友元声明
};
// 全局形式操作符函数
Human operator+(const Human& l, const Human& r){return Human(l.m_age+r.m_age, (l.m_name+"+"+r.m_name).c_str());
}int main(void){Human a(22,"张飞"), b(20,"赵云"); // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值Human res = a + b; // ==> a.operator+(b) 或 operator+(a,b)res.getInfo();res = c + d; // ==> c.operator+(d) 或 operator+(c,d)res.getInfo();res = Human(45,"黄忠") + Human(35,"刘备"); // ==> Human(45,"黄忠").operator+(Human(35,"刘备")) 或 // operator+(Human(45,"黄忠"),Human(35,"刘备"))res.getInfo();return 0;
}
赋值类双目操作符:=、+=、-=、*=、/=等
- 右操作数可以为非常左值、常左值或右值,但左操作数必须为非常左值
- 表达式结果为左操作数本身(而非副本)
// 赋值类双目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}// 成员形式操作符函数Human& operator+=(const Human& r){this->m_age = this->m_age + r.m_age;this->m_name = this->m_name + "+" + r.m_name;return *this;}
private:int m_age;string m_name;friend Human operator+(const Human& l,const Human& r); // 友元声明
};全局形式操作符函数
//Human& operator+(Human& l, const Human& r){
// l->m_age = l->m_age + r.m_age;
// l->m_name = l->m_name + "+" + r.m_name;
// return *l;
//}int main(void){Human a(22,"张飞"), b(20,"赵云"); // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值((a+=b)+=c)+=Human(45,"黄忠");a.getInfo();return 0;
}
比较类双目操作符:>、<、==、<=、>=等
- 左右操作数为非常左值、常左值或右值
- 表达式结果为 bool
// 比较类双目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}
// // 成员形式操作符函数
// bool operator==(/*const Human* this */ const Human& that)const{
// return this->m_age==that.m_age && this->m_name==that.m_name;
// }
// bool operator!=(/*const Human* this */ const Human& that)const{return this->m_age!=that.m_age || this->m_name!=that.m_name;
// return !(*this==that);//使用operator==
// }
private:int m_age;string m_name;friend bool operator==(const Human& l, const Human& r); // 友元声明friend bool operator!=(const Human& l, const Human& r); // 友元声明
};
// 全局形式操作符函数
bool operator==(const Human& l, const Human& r){return l.m_age==r.m_age && l.m_name==r.m_name;
}
bool operator!=(const Human& l, const Human& r){
// return l.m_age!=r.m_age || l.m_name!=r.m_name;return !(l==r);//使用operator==
}int main(void){Human a(22,"张飞"), b(20,"赵云"); // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值cout << (a == b) << endl; //0 ==> a.operator==(b) 或者 ...cout << (a != b) << endl; //1 ==> a.operator!=(b) 或者 ...cout << (c == d) << endl; //0 ==> c.operator==(d) 或者 ...cout << (c != d) << endl; //1 ==> c.operator!=(d) 或者 ...cout << (Human(45,"黄忠") == Human(35,"刘备")) << endl; //0 ==> Human(45,"黄忠").operator==(Human(35,"刘备")) 或者 ...cout << (Human(45,"黄忠") != Human(35,"刘备")) << endl; //1 ==> Human(45,"黄忠").operator!=(Human(35,"刘备")) 或者 ...return 0;
}
经典单目操作符
运算类单目操作符:-、~、!等
- 操作数为非常左值、常左值或右值
- 表达式的结果为右值
// 运算类单目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}// 成员形式操作符函数Human operator-(/* const Human* this */)const{return Human(-this->m_age,("-"+this->m_name).c_str());}
private:int m_age;string m_name;
// friend Human operator-(const Human& l); // 友元声明
};//Human operator-(const Human& l){
// return Human(-l.m_age,("-"+l.m_name).c_str());
//}
int main(void){Human a(22,"张飞"), b(20,"赵云"); // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值Human res = -a; // ==> a.operator-() 或 ...res.getInfo();//姓名:-张飞, 年龄:-22res = -c; // ==> c.operator-() 或 ...res.getInfo();//姓名:-关羽, 年龄:-25res = -Human(45,"黄忠"); // ==> Human(45,"黄忠").operator-() 或 ...res.getInfo();//姓名:-黄忠, 年龄:-45return 0;
}
前自增减类单目操作符: 前++、前–
- 操作数为非常左值
- 表达式的结果为操作数本身(而非副本)
后自增减类单目操作符: 后+ +、后–
- 操作数为非常左值
- 表达式的结果为右值,且为自增减以前的值
// 自增减类单目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}//成员形式操作符函数
// // 前++ ++a
// Human& operator++(/* Human* this */){
// this->m_age+=1; // 直接加1
// this->m_name+="a"; // 直接加
// return *this;
// }后++ a++
// Human operator++(/* Human* this */int){
// Human old = *this; // 备份原来的值
// this->m_age+=1; // 直接加1
// this->m_name+="a"; // 直接加
// return old; // 返回原来的值
// }
private:int m_age;string m_name;friend Human& operator++(Human& l); // 友元声明friend Human operator++(Human& l,int); // 友元声明
};// 前++ ++aHuman& operator++(Human& l){l.m_age+=1; // 直接加1l.m_name+="a"; // 直接加return l;}// 后++ a++Human operator++(Human& l,int){Human old = l; // 备份原来的值l.m_age+=1; // 直接加1l.m_name+="a"; // 直接加return old; // 返回原来的值}int main(void){Human a(22,"张飞"), b(20,"赵云"); // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值//姓名:张飞a, 年龄:23(++a).getInfo(); // a.operator++() 或 ...//姓名:赵云, 年龄:20(/*|...|*/b++).getInfo(); // b.operator++(0) 或 ...//姓名:赵云a, 年龄:21b.getInfo();return 0;
}
其他操作符
输出操作符: <<
- 左操作数为非常左值形式的输出流(ostream)对象,右操作数为左值或右值
- 表达式的结果为左操作数本身(而非副本)
- 左操作数的类型为ostream,若以成员函数形式重载该操作符,就应将其定义为ostream类的成员,该类为标准库提供,无法添加新的成员,因此只能以全局函数形式重载该操作符
ostream& operator< < (ostream& os, const RIGHT& right) { ...}
// 输入/输出流操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}
/* void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}*/// 成员形式操作符函数
private:int m_age;string m_name;friend ostream& operator<<(ostream& os, const Human& that);friend istream& operator>>(istream& is, Human& that);
};
// 全局形式操作符函数
ostream& operator<<(ostream& os, const Human& that){os << "姓名:" << that.m_name << ", 年龄:" << that.m_age;return os;
}//istream& operator>>(istream& is, Human& that){
// is >> that.m_name >> that.m_age;
// return is;
//}int main(void){Human a(22,"张飞"); // 非常左值const Human b(20,"赵云"); // 常左值cout << a << endl; // cout.operator<<(a) 或 operator<<(cout,a)cout << b << endl; // cout.operator<<(b) 或 operator<<(cout,b)cout << Human(45,"黄忠") << endl; // cout.operator<<(Human(45,"黄忠")) 或 operator<<(cout,Human(45,"黄忠"))// cin >> a; // cin.operator>>(a) 或 operator>>(cin,a)cout << a << endl;return 0;
}
输入操作符: >>
- 左操作数为非常左值形式的输入流(istream)对象,右操作数为非常左值
- 表达式的结果为左操作数本身(而非副本)
- 左操作数的类型为istream,若以成员函数形式重载该操作符,就应将其定义为istream类的成员,该类为标准库提供,无法添加新的成员,因此只能以全局函数形式重载该操作符
istream& operator>> (istream& is, RIGHT& right) { ...}
// 输入/输出流操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}
/* void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}*/// 成员形式操作符函数
private:int m_age;string m_name;friend ostream& operator<<(ostream& os, const Human& that);friend istream& operator>>(istream& is, Human& that);
};
// 全局形式操作符函数
ostream& operator<<(ostream& os, const Human& that){os << "姓名:" << that.m_name << ", 年龄:" << that.m_age;return os;
}istream& operator>>(istream& is, Human& that){is >> that.m_name >> that.m_age;return is;
}int main(void){Human a(22,"张飞"); // 非常左值cin >> a; // cin.operator>>(a) 或 operator>>(cin,a)cout << a << endl;return 0;
}
下标操作符:[]
- 一般用于在容器类型中以下标方式获取数据元素
- 非常容器的元素为非常左值,常容器的元素为常左值
类型转换操作符
若源类型是基本类型,目标类型是类类型,则只能通过类型转换构造函数实现自定义类型转换
class 目标类型{目标类型(const 源类型& src){ ... }
}
若源类型是类类型,目标类型是基本类型,则只能通过类型转换操作符函数 实现自定义类型转换
class 源类型{operator 目标类型(void) const { ...}
}
若源类型和目标类型都是类类型 (而非基本类型) ,则既可以通过类型转换构造函数也可以通过类型转换操作符函数实现自定义类型转换,但不要两者同时使用
若源类型和目标类型都是基本类型,则无法实现自定义类型转换,基本类型间的类型转换规则完全由编译器内置
类型转换构造函数和类型转换操作符函数
// 类型转换构造函数和类型转换操作符函数
#include <iostream>
using namespace std;class Integer{
public:Integer(int i):m_i(i){//【int m_i = i;】cout << "Integer类的类型转换构造函数被调用" << endl;}operator int(/* const Integer* this */)const{cout << "Integer类的类型转换操作符函数被调用" << endl;return this->m_i;}
private:int m_i;
};int main(void){int n = 666;// int --> Integer(基本类型-->类类型)Integer ix = n; // 定义匿名Integer对象,利用匿名Integer对象.Integer(n) --> 触发类型转换构造函数// Integer ix = n.operator Integer() --> int类中没有一个operator Integer(走不通) // Integer --> int(类类型 --> 基本类型)int m = ix; // 定义匿名int对象,利用匿名int对象.int(ix)-->int类中没有一个形参是Integer类型的构造函数(走不通)// int m = ix.operator int() --> 触发类型转换操作符函数return 0;
}
// 类型转换构造函数和类型转换操作符函数
#include <iostream>
using namespace std;class Dog; // 短式声明/前置声明class Cat{
public:Cat(const char* name):m_name(name){// [string m_name(name);]}void talk() {cout << m_name << ": 喵喵~~~" << endl;}operator Dog(/* const Cat* this */)const; // 声明
private:string m_name;friend class Dog; // 友元声明
};class Dog{
public:Dog(const char* name):m_name(name){// [string m_name=name;]}
/* Dog(const Cat& that):m_name(that.m_name){ // 类型转换构造(定制了Cat-->Dog的转换规则)//【string m_name = that.m_name;】cout << "Dog类的类型转换构造函数被调用" << endl;}*/void talk() {cout << m_name << ": 汪汪~~~" << endl;}
private:string m_name;
};
Cat::operator Dog(/* const Cat* this */)const{ // 定义cout << "Cat类的类型转换操作符函数被调用" << endl;return Dog(this->m_name.c_str());
}int main( void ) {Cat smallwhite("小白"); Dog bigyellow = smallwhite; // 定义匿名Dog类对象,利用匿名Dog类对象.Dog(smallwhite)-->触发Dog类的类型转换构造函数// Dog bigyellow = smallwhite.operator Dog() --> 触发Cat类的类型转换操作符函数return 0;
}
操作符重载的局限
不是所有的操作符都能重载,以下操作符不能重载
- 作用域限定操作符(
::) - 直接成员访问操作符(
.) - 条件操作符(
?:) - 字节长度操作符(
sizeof) - 类型信息操作符(
typeid)
无法重载所有操作数均为基本类型的操作符: 如实现 1+1=3
c++的前++和后++
- 在C语言中
前++: 先加1,再使用 ++a
后++: 先使用,再加1 a++ - 在C++语言中,不管是前++还是后++,都是直接加1(内部原理和C语言并不同)
但是C++希望用户感觉和C一样
c++的前++和后++的区别
- 表达式方式区别:i++是先取变量i,再将变量i值+1;而++i是先将变量i值+1,再取变量i。在循环遍历容器变量时,这两种方式的结果都是一样的,但是,本质的效率上有很大的区别,下面介绍另一种效率区别。
- 效率:两种方式iterator遍历的次数是相同的,但在STL中效率不同,前++返回引用,后++返回一个临时对象,因为iterator是类模板,使用 it++这种形式要返回一个无用的临时对象,而it++是函数重载,所以编译器无法对其进行优化,所以每遍历一个元素,你就创建并销毁了一个无用的临时对象。C++的标准库,还有符合标准C++的教材,除了特殊需要和对内置类型外,基本都是使用++it来进行元素遍历的,不管是源代码还是教材中都是如此。
下面是标准库源码:

相关文章:
8、操作符重载
友元 可以通过friend关键字,把一个全局函数、另一个类的成员函数或者另一个类整体,声明为授权类的友元友元拥有访问授权类任何非公有成员的特权友元声明可以出现在授权类的公有、私有或者保护等任何区域且不受访问控制限定符的约束友元不是成员…...
前端组件库开发
通常我们会使用很多组件库,有时候我们会去看源码比如element,antd,然后发现多少是按需导出,和vue.use全局注册,依赖于框架的拓展。 组件库的开发依赖框架的版本和node的版本,这个是需要说明的,然…...
自定义日志打印功能--C++
一、介绍 日志是计算机程序中用于记录运行时事件和状态的重要工具。通过记录关键信息和错误情况,日志可以帮助程序开发人员和维护人员追踪程序的执行过程,排查问题和改进性能。 在软件开发中,日志通常记录如下类型的信息: 事件信…...
gitlab注册无中国区电话验证问题
众所周知gitlab对中国区不友好,无法直接注册,页面无法选择86的手机号进行验证码发送。 Google上众多的方案是修改dom,而且时间大约是21年以前。 修改dom,对于现在的VUE、React框架来说是没有用的,所以不用尝试。 直接看…...
【JAVA基础题目练习】----第二天
JAVA基础题目练习 1. 键盘录入数据,比较大小2. 代码重构(简化代码,少做判断)3. 键盘录入月份的值,输出对应的季节4. 获取三个数据中的最大值使用IF语句5. 用switch语句实现键盘录入月份,输出对应的季节6. 求…...
node.js和npm的安装与环境配置(2023最新版)
目录 安装node.js测试是否安装成功测试npm环境配置更改环境变量新建系统变量 安装node.js 1、进入官网下载:node.js官网 我选择的是windows64位的,你可以根据自己的实际情况选择对应的版本。 2、下载完成,安装。 打开安装程序 接受协议 选…...
ke14--10章-1数据库JDBC介绍
注册数据库(两种方式),获取连接,通过Connection对象获取Statement对象,使用Statement执行SQL语句。操作ResultSet结果集 ,回收数据库资源. 需要语句: 1Class.forName("DriverName");2Connection conn DriverManager.getConnection(String url, String user, String…...
【IC验证】perl脚本——分析前/后仿用例回归情况
目录 1 脚本名称 2 脚本使用说明 3 nocare_list文件示例 4 脚本执行方法 5 postsim_result.log文件示例 6 脚本代码 1 脚本名称 post_analysis 2 脚本使用说明 help:打印脚本说明信息 命令:post_analysis help 前/后仿结束后,首先填…...
Ansible适合的场景是什么?
Ansible将编排与配置管理、供应和应用程序部署结合并统一在一个易于使用的平台上。Ansible的一些主要场景包括: 配置管理:集中配置文件管理和部署是Ansible的一个常见场景。 应用程序部署:当使用Ansible定义应用程序,并使用Ansible Tower管…...
Flink 读写 HBase 总结
前言 总结 Flink 读写 HBase 版本 Flink 1.15.4HBase 2.0.2Hudi 0.13.0官方文档 https://nightlies.apache.org/flink/flink-docs-release-1.17/zh/docs/connectors/table/hbase/ Jar包 https://repo1.maven.org/maven2/org/apache/flink/flink-sql-connector-hbase-2.2/1…...
记录一次chatGPT人机协同实战辅助科研——根据词库自动进行情感分析
有一个Excel中的一列,读取文本判断文本包含积极情感词.txt和消极情感词.txt的个数,分别生成两列统计数据 请将 ‘your_file.xlsx’ 替换为你的Excel文件名,Your Text Column’替换为包含文本的列名。 这个程序首先读取了积极和消极情感词&…...
Java_LinkedList链表详解
目录 前言 ArrayList的缺陷 链表 链表的概念及结构 链表的种类 1.单向或双向 2.带头或不带头 3.循环或不循环 LinkedList的使用 什么是LinkedList LinkedList的使用 LinkedList的构造 LinkedList的其他常用方法介绍 LinkedList的遍历 ArrayList和LinkedList的…...
MacOS 12 开放指定端口 指定ip访问
MacOS 12 开放指定端口 指定ip访问 在 macOS 上开放一个端口,并指定只能特定的 IP 访问,你可以使用 macOS 内置的 pfctl(Packet Filter)工具来实现。 以下是一些基本的步骤: 1、 编辑 pf 配置文件: 打开 /…...
LeedCode刷题---滑动窗口问题
顾得泉:个人主页 个人专栏:《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂,年薪百万! 一、长度最小的子数组 题目链接:长度最小的子数组 题目描述 给定一个含有 n 个正整数的数组和一个正整数 target 。…...
leetcode24. 两两交换链表中的节点
题目描述 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入:head [1,2,3,4] 输出&#…...
TCP传输层详解(计算机网络复习)
介绍:TCP/IP包含了一系列的协议,也叫TCP/IP协议族,简称TCP/IP。该协议族提供了点对点的连接机制,并将传输数据帧的封装、寻址、传输、路由以及接收方式都予以标准化 TCP/IP的分层模型 在讲TCP/IP协议之前,首先介绍一…...
【LuatOS】简单案例网页点灯
材料 硬件:合宙ESP32C3简约版,BH1750光照度模块,0.96寸OLED(4P_IIC),杜邦线若干 接线: ESP32C3.GND — OLED.GND — BH1750.GND ESP32C3.3.3V — OLED.VCC — BH1750.VCC ESP32C3.GPIO5 — OLED.SCL — BH1750.SCL E…...
百度APP iOS端包体积50M优化实践(七)编译器优化
一. 前言 百度APP iOS端包体积优化系列文章的前六篇重点介绍了包体积优化整体方案、图片优化、资源优化、代码优化、无用类优化、HEIC图片优化实践和无用方法清理,图片优化是从无用图片、Asset Catalog和HEIC格式三个角度做深度优化;资源优化包括大资源…...
STM32-新建工程(标准库)
目录 STM32F10x新建工程(标准库) 移植文件夹 新建工程 添加启动文件和必需文件 在工程中加载新添加的文件 在工程中添加文件路径 在工程中添加main函数 添加lib库 添加必需文件 添加宏定义 点亮LED(标准库) STM32F10x新…...
Android集成科大讯飞语音识别与语音唤醒简易封装
目录 一、语音唤醒部分 1、首先在科大讯飞官网注册开发者账号 2、配置唤醒词然后下载sdk 3、选择对应功能下载 4、语音唤醒lib包全部复制到工程目录下 5、把语音唤醒词文件复制到工程的assets目录 6、复制对应权限到AndroidManifest.xml中 7、唤醒工具类封装 二、语音识…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
