当前位置: 首页 > news >正文

[c++] 自写 MyString 类

实现了 MyString 类,同时实现了运算符重载,重载的运算符包括 <、>、==、!=、<<、>>、[] 等。

如果一个类重载了某个运算符,那么对这个类的对象进行操作的时候便会使用类重载的运算符。比如下边代码 MyString 类中重载了 <、>、==、!=、<<、>> 运算符,那么使用这些运算符操作对象的时候,便会使用对象重载之后的运算符。

(1) <、>、==、!=

① 4 个运算符重载,可以声明为友元函数,也可以声明为类的成员函数

② 声明友元函数时,形参是两个;声明为成员函数时,形参是一个

③ 对象 O1 和 O2 进行比较,成员函数是 O1.operator < (O1);友元函数是 operator < (O1, O2)

④ 声明为成员函数时,默认会带一个 this 指针,*this 是左操作数

(2) <<,>> 流操作符,需要声明为友元函数,不能声明为成员函数

(3) 不能创建新的运算符,只能重载已有的运算符

如下代码,<、>、==、!=、<<、>> 均声明为友元函数。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>class MyString {
public:MyString(); // 默认构造函数MyString(int n, char c); // 普通构造函数MyString(const char *str); // 普通构造函数MyString(const MyString &str); // 拷贝构造函数MyString& operator = (char *str); // 重载 =,使用字符串赋值MyString& operator = (const MyString &s); // 重载 =,使用对象赋值~MyString(); // 析构函数char& operator[] (int i); // 重载 [], 实现数组操作const char& operator[] (int i) const; // 重载 [],事项数组操作,对象为常量MyString& operator += (const MyString& str); // 重载 +=,与对象相加MyString& operator += (const char *str); // 重载 +=,与字符串相加friend std::ostream& operator << (std::ostream& out, MyString& str); // 重载 <<,实现输出流friend std::istream& operator >> (std::istream& in, MyString& str); // 重载 >>,实现输入流friend bool operator < (const MyString& left, const MyString& right); // 重载 <friend bool operator > (const MyString& left, const MyString& right); // 重载 >friend bool operator == (const MyString& left, const MyString& right); // 重载 ==friend bool operator != (const MyString& left, const MyString& right); // 重载 !=char *GetData() const;// 对象被声明为 const,那么这个对象调用的函数也需要是 const 类型int Size() const;private:int size;char *data = nullptr;
};MyString::MyString() {// 默认构造函数,只包括一个字符 '\0'printf("MyString()\n");data = new char[1];*data = '\0';size = 0;
}MyString::MyString(int n, char c) {printf("MyString(int n, char c), n = %d, c = %c\n", n, c);data = new char[n + 1];for (int i = 0; i < n; i++) {*(data + i) = c;}*(data + n) = '\0';size = n;
}MyString::MyString(const char *str) {printf("MyString(const char *str), str = %s\n", str);if (str == nullptr) {data = new char[1];*data = '\0';size = 0;} else {data = new char[strlen(str) + 1];strcpy(data, str);size = strlen(str);}
}MyString::MyString(const MyString &str) {printf("MyString(const MyString &str), str = %s\n",  str.GetData());data = new char[str.size + 1];strcpy(data, str.data);size = str.size;
}MyString& MyString::operator = (char *str) {printf("operator =, MyString = char *, str = %s\n", str);if (data != nullptr) {delete []data;}data = new char[strlen(str) +1];strcpy(data, str);return *this;
}MyString&MyString::operator = (const MyString& str) {printf("operator =, MyString = MyString, str = %s\n", str.GetData());if (this == &str) {return *this;}if (data != nullptr) {delete []data;}data = new char[str.size + 1];strcpy(data, str.data);return *this;
}MyString::~MyString() {if (data != nullptr) {delete []data;data = nullptr;size = 0;}
}char& MyString::operator [](int i) {return data[i];
}const char& MyString::operator[] (int i) const {printf("operator [], const\n");return data[i];
}MyString& MyString::operator +=(const MyString& s) {printf("operator += MyString, str = %s\n", s.GetData());int length = size + s.size + 1;char *tmp = data;data = new char[length];size = length - 1;strcpy(data, tmp);strcat(data, s.data);delete []tmp;return *this;
}MyString& MyString::operator += (const char *str) {printf("operator += char *, str = %s\n", str);if (str == nullptr) {return *this;}int length = size + strlen(str) + 1;char *tmp = data;data = new char[length];size = length - 1;strcpy(data, tmp);strcat(data, str);delete []tmp;return *this;
}int MyString::Size() const {return size;
}char* MyString::GetData() const {return data;
}std::ostream& operator << (std::ostream &out, MyString &str) {for (int i = 0; i < str.Size(); i++) {out << str[i] << " ";}return out;
}std::istream& operator >> (std::istream& in, MyString& str) {char p[50];in.getline(p, 50);str = p;return in;
}bool operator < (const MyString& left, const MyString& right) {int i = 0;while (left[i] != '\0' && right[i] != '\0' && left[i] == right[i]) {i++;}if (left[i] < right[i]) {return true;}return false;
}bool operator > (const MyString& left, const MyString& right) {int i = 0;while (left[i] != '\0' && right[i] != '\0' && left[i] == right[i]) {i++;}if (left[i] > right[i]) {return true;}return false;
}bool operator == (const MyString& left, const MyString& right) {if (left.Size() != right.Size()) {return false;}int i = 0;while (left[i] != '\0' && right[i] != '\0') {if (left[i] != right[i]) {return false;}i++;}return true;
}bool operator != (const MyString& left, const MyString& right) {if (left.Size() != right.Size()) {return true;}int i = 0;while (left[i] != '\0' && right[i] != '\0') {if (left[i] != right[i]) {return true;}i++;}return false;
}int main() {printf("构造 --------------------------------\n");MyString s1(3, 'a'); // 默认构造函数MyString s2(s1); // 拷贝构造函数MyString s3("abcdefghijklmn"); // 通过 char * 来构造函数MyString s4; // 空的字符串printf("\noperator << --------------------------------\n");std::cout << "s1: " << s1 << std::endl; // 输出字符串,使用重载的运算符 <<std::cout << "s2: " << s2 << std::endl;std::cout << "s3: " << s3 << std::endl;std::cout << "s4: " << s4 << std::endl;printf("\noperator = --------------------------------\n");s4 = s3; // 字符串赋值,使用字符串对象赋值std::cout << "s4: " << s4 << std::endl;s4 = "abcd"; // 使用 char * 赋值std::cout << "s4: " << s4 << std::endl;std::cout << "s4[2] = " << s4[2] << std::endl;printf("\noperator += --------------------------------\n");s4 += "mmmm";std::cout << "s4: " << s4 << std::endl;s4 += s2;std::cout << "s4: " << s4 << std::endl;printf("\noperator >> --------------------------------\n");std::cin >> s2;std::cout << "s2: " << s2 << std::endl;printf("\n<, >, ==, != --------------------------------\n");MyString t1 = "1234";MyString t2 = "1234";MyString t3 = "12345";MyString t4 = "12335";std::cout << "t1 == t2 ? " << (t1 == t2) << std::endl;std::cout << "t1 < t3 ? " << (t1 < t3) << std::endl;std::cout << "t1 > t4 ?  " << (t1 > t4) << std::endl;std::cout << "t1 != t4 ? " << (t1 != t4) << std::endl;return 0;
}

如下代码,<、>、==、!= 声明为成员函数,当成员函数和友元函数同时存在时,优先选用成员函数。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>class MyString {
public:MyString(); // 默认构造函数MyString(int n, char c); // 普通构造函数MyString(const char *str); // 普通构造函数MyString(const MyString &str); // 拷贝构造函数MyString& operator = (char *str); // 重载 =,使用字符串赋值MyString& operator = (const MyString &s); // 重载 =,使用对象赋值~MyString(); // 析构函数char& operator[] (int i); // 重载 [], 实现数组操作const char& operator[] (int i) const; // 重载 [],事项数组操作,对象为常量MyString& operator += (const MyString& str); // 重载 +=,与对象相加MyString& operator += (const char *str); // 重载 +=,与字符串相加friend std::ostream& operator << (std::ostream& out, MyString& str); // 重载 <<,实现输出流friend std::istream& operator >> (std::istream& in, MyString& str); // 重载 >>,实现输入流friend bool operator < (const MyString& left, const MyString& right); // 重载 <friend bool operator > (const MyString& left, const MyString& right); // 重载 >friend bool operator == (const MyString& left, const MyString& right); // 重载 ==friend bool operator != (const MyString& left, const MyString& right); // 重载 !=bool operator < (const MyString& str); // 重载 <bool operator > (const MyString& str); // 重载 >bool operator == (const MyString& str); // 重载 ==bool operator != (const MyString& str); // 重载 !=char *GetData() const;// 对象被声明为 const,那么这个对象调用的函数也需要是 const 类型int Size() const;private:int size;char *data = nullptr;
};MyString::MyString() {// 默认构造函数,只包括一个字符 '\0'printf("MyString()\n");data = new char[1];*data = '\0';size = 0;
}MyString::MyString(int n, char c) {printf("MyString(int n, char c), n = %d, c = %c\n", n, c);data = new char[n + 1];for (int i = 0; i < n; i++) {*(data + i) = c;}*(data + n) = '\0';size = n;
}MyString::MyString(const char *str) {printf("MyString(const char *str), str = %s\n", str);if (str == nullptr) {data = new char[1];*data = '\0';size = 0;} else {data = new char[strlen(str) + 1];strcpy(data, str);size = strlen(str);}
}MyString::MyString(const MyString &str) {printf("MyString(const MyString &str), str = %s\n",  str.GetData());data = new char[str.size + 1];strcpy(data, str.data);size = str.size;
}MyString& MyString::operator = (char *str) {printf("operator =, MyString = char *, str = %s\n", str);if (data != nullptr) {delete []data;}data = new char[strlen(str) +1];strcpy(data, str);return *this;
}MyString&MyString::operator = (const MyString& str) {printf("operator =, MyString = MyString, str = %s\n", str.GetData());if (this == &str) {return *this;}if (data != nullptr) {delete []data;}data = new char[str.size + 1];strcpy(data, str.data);return *this;
}MyString::~MyString() {if (data != nullptr) {delete []data;data = nullptr;size = 0;}
}char& MyString::operator [](int i) {return data[i];
}const char& MyString::operator[] (int i) const {return data[i];
}MyString& MyString::operator +=(const MyString& s) {printf("operator += MyString, str = %s\n", s.GetData());int length = size + s.size + 1;char *tmp = data;data = new char[length];size = length - 1;strcpy(data, tmp);strcat(data, s.data);delete []tmp;return *this;
}MyString& MyString::operator += (const char *str) {printf("operator += char *, str = %s\n", str);if (str == nullptr) {return *this;}int length = size + strlen(str) + 1;char *tmp = data;data = new char[length];size = length - 1;strcpy(data, tmp);strcat(data, str);delete []tmp;return *this;
}int MyString::Size() const {return size;
}char* MyString::GetData() const {return data;
}std::ostream& operator << (std::ostream &out, MyString &str) {for (int i = 0; i < str.Size(); i++) {out << str[i] << " ";}return out;
}std::istream& operator >> (std::istream& in, MyString& str) {char p[50];in.getline(p, 50);str = p;return in;
}bool operator < (const MyString& left, const MyString& right) {int i = 0;while (left[i] != '\0' && right[i] != '\0' && left[i] == right[i]) {i++;}if (left[i] < right[i]) {return true;}return false;
}bool operator > (const MyString& left, const MyString& right) {int i = 0;while (left[i] != '\0' && right[i] != '\0' && left[i] == right[i]) {i++;}if (left[i] > right[i]) {return true;}return false;
}bool operator == (const MyString& left, const MyString& right) {if (left.Size() != right.Size()) {return false;}int i = 0;while (left[i] != '\0' && right[i] != '\0') {if (left[i] != right[i]) {return false;}i++;}return true;
}bool operator != (const MyString& left, const MyString& right) {if (left.Size() != right.Size()) {return true;}int i = 0;while (left[i] != '\0' && right[i] != '\0') {if (left[i] != right[i]) {return true;}i++;}return false;
}//
bool MyString::operator < (const MyString& str) {int i = 0;while (data[i] != '\0' && str[i] != '\0' && data[i] == str[i]) {i++;}if (data[i] < str[i]) {return true;}return false;
}bool MyString::operator > (const MyString& str) {int i = 0;while (data[i] != '\0' && str[i] != '\0' && data[i] == str[i]) {i++;}if (data[i] > str[i]) {return true;}return false;
}bool MyString::operator == (const MyString& str) {if (size != str.Size()) {return false;}int i = 0;while (data[i] != '\0' && str[i] != '\0') {if (data[i] != str[i]) {return false;}i++;}return true;
}bool MyString::operator != (const MyString& str) {if (size != str.Size()) {return true;}int i = 0;while (data[i] != '\0' && str[i] != '\0') {if (data[i] != str[i]) {return true;}i++;}return false;
}int main() {printf("构造 --------------------------------\n");MyString s1(3, 'a'); // 默认构造函数MyString s2(s1); // 拷贝构造函数MyString s3("abcdefghijklmn"); // 通过 char * 来构造函数MyString s4; // 空的字符串printf("\noperator << --------------------------------\n");std::cout << "s1: " << s1 << std::endl; // 输出字符串,使用重载的运算符 <<std::cout << "s2: " << s2 << std::endl;std::cout << "s3: " << s3 << std::endl;std::cout << "s4: " << s4 << std::endl;printf("\noperator = --------------------------------\n");s4 = s3; // 字符串赋值,使用字符串对象赋值std::cout << "s4: " << s4 << std::endl;s4 = "abcd"; // 使用 char * 赋值std::cout << "s4: " << s4 << std::endl;std::cout << "s4[2] = " << s4[2] << std::endl;printf("\noperator += --------------------------------\n");s4 += "mmmm";std::cout << "s4: " << s4 << std::endl;s4 += s2;std::cout << "s4: " << s4 << std::endl;printf("\noperator >> --------------------------------\n");std::cin >> s2;std::cout << "s2: " << s2 << std::endl;printf("\n<, >, ==, != --------------------------------\n");MyString t1 = "1234";MyString t2 = "1234";MyString t3 = "12345";MyString t4 = "12335";std::cout << "t1 == t2 ? " << (t1 == t2) << std::endl;std::cout << "t1 < t3 ? " << (t1 < t3) << std::endl;std::cout << "t1 > t4 ?  " << (t1 > t4) << std::endl;std::cout << "t1 != t4 ? " << (t1 != t4) << std::endl;return 0;
}

相关文章:

[c++] 自写 MyString 类

实现了 MyString 类&#xff0c;同时实现了运算符重载&#xff0c;重载的运算符包括 <、>、、!、<<、>>、[] 等。 如果一个类重载了某个运算符&#xff0c;那么对这个类的对象进行操作的时候便会使用类重载的运算符。比如下边代码 MyString 类中重载了 <、…...

三、阅读器开发--4、阅读器目录、全文搜索功能开发

1、阅读器目录 1.1、实现目录 先实现目录的布局 定义一个蒙版&#xff0c;充满整个屏幕浮在阅读器上方&#xff0c;左侧为目录右侧为背景&#xff0c;目录下方包含一个tab&#xff0c;点击后会切换不同的内容&#xff0c;这里tab是目录、书签&#xff0c;这里可以通过如下的…...

AMEYA360代理 | 江苏长晶科技FST2.0高性能 IGBT产品介绍

江苏长晶科技股份有限公司是一家专业从事半导体产品研发、生产和销售的企业。自2019年起&#xff0c;连续4年被中国半导体行业协会评为 “功率器件十强企业”。2021年开始自主研发有着“工业CPU”之称的IGBT&#xff0c;截至2023年Q3在家电/工业/新能源等行业实现8款产品市场应…...

基于springboot+vue+Mysql的网上图书商城

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

阿里云服务器多少钱一个月?低至5元1个月

阿里云服务器一个月多少钱&#xff1f;最便宜5元1个月。阿里云轻量应用服务器2核2G3M配置61元一年&#xff0c;折合5元一个月&#xff0c;2核4G服务器30元3个月&#xff0c;2核2G3M带宽服务器99元12个月&#xff0c;轻量应用服务器2核4G4M带宽165元12个月&#xff0c;4核16G服务…...

LeetCode第五天(442. 数组中重复的数据)

给你一个长度为 n 的整数数组 nums &#xff0c;其中 nums 的所有整数都在范围 [1, n] 内&#xff0c;且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数&#xff0c;并以数组形式返回。 你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问…...

chatgpt正面案例合集

现在可以用百度 百度安全验证 chatgpt用来搜索软件使用指令太牛了_个人渣记录仅为自己搜索用的博客-CSDN博客 chatgpt 使用案例 根据不同的目标群体变更文案和表达_个人渣记录仅为自己搜索用的博客-CSDN博客 倾听能力 和哪些基础能力相关 ,如何提高 chatgpt_个人渣记录仅为自…...

今日讲讲路由配置

下载安装路由 1. 下载安装路由库 npm i vue-router 2. 在 src 中新建 views 文件夹&#xff0c;在其中新建页面 3. 在 src 中新建一个 router 文件夹&#xff0c;其中新建一个 index.js import { createRouter, createWebHashHistory } from vue-router; // 导入页面 imp…...

【Rust】Shared-State Concurrency

Shared-State Concurrency channel类似于single ownership. 而shared memory类似与multiple ownership. multiple ownership是难于管理的. smarter pointer也是multiple ownership的. Rust的type system和ownership rules帮助实现正确的multiple ownership管理。 Using Mute…...

连接数据库(MySQL)的JDBC

目录 JDBC简介快速入门API详解DriverManager&#xff08;驱动管理类&#xff09;注册驱动&#xff1a;获取数据库连接(对象)&#xff1a; Connection&#xff08;数据库连接对象&#xff09;获取执行SQL的对象管理事务 Statement(执行SQL语句)执行DML、DDL语句执行DQL语句 Resu…...

golang通过参数控制HTTP server是否使用基本认证

之前写的《golang实现一个BasicAuth的HTTP server》一定会做基本认证。 本例给出了如何通过启动时候指定的参数来控制是否做基本认证 代码对比和解释 给出与上一篇中源码的diff adminhpc-1:~/go/auth_http$ diff -ruN http_rpc_server.go_bak http_rpc_server.go --- http_rp…...

javaSwing坦克大战游戏

在游戏开发领域&#xff0c;坦克大战是一款经典的游戏&#xff0c;其简单而又耐玩的玩法吸引了无数玩家。而今&#xff0c;在Java编程技术的支持下&#xff0c;我们可以用Java Swing技术轻松实现这款经典游戏。本文将介绍如何使用Java Swing技术编写坦克大战游戏&#xff0c;并…...

【面试题】数据底层原理:Elasticsearch写入流程解析

前言&#xff1a;本篇博客将介绍Elasticsearch的数据底层原理&#xff0c;涉及数据写入的过程以及相关概念。我们将深入探讨buffer、translog、refresh、commit、flush和merge等核心概念&#xff0c;帮助您更好地理解Elasticsearch的数据存储机制。 写入数据的基本过程 Elast…...

牛客论坛spring initializer选用的构件

spring版本&#xff1a;2.1.5.RELEASE java版本&#xff1a;8 pom文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…...

【Java程序设计】【C00385】基于(JavaWeb)Springboot的员工信息管理系统(有论文)

基于&#xff08;JavaWeb&#xff09;Springboot的员工信息管理系统 项目简介项目获取开发环境项目技术运行截图 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c…...

【Linux进阶之路】理解UDP,成为TCP。

前言 学了TCP 和UDP之后&#xff0c;感觉UDP就像是初入职场的年轻人&#xff0c;两耳不闻 “窗外事”&#xff0c;只管尽力地把自己的事情做好&#xff0c;但收获的却是不可靠&#xff0c;而TCP更像是涉世极深的"职场老油条"&#xff0c;给人的感觉就是 “城府极深&a…...

Linux实用操作

一&#xff0c;各类小技巧&#xff08;快捷键&#xff09; 强制停止 ctrlc强制停止 Linux某些程序的运行&#xff0c;如果想要强制停止它&#xff0c;可以使用快捷键ctrlc 命令输入错误,也可以通过快捷键ctrlc,退出当前输入,重新输入 退出、登出 ctrld退出或登出 可以通过快…...

OpenJudge - 12:加密的病历单

总时间限制: 1000ms 内存限制: 65536kB 描述 小英是药学专业大三的学生&#xff0c;暑假期间获得了去医院药房实习的机会。 在药房实习期间&#xff0c;小英扎实的专业基础获得了医生的一致好评&#xff0c;得知小英在计算概论中取得过好成绩后&#xff0c;主任又额外交给她一…...

QGIS编译(跨平台编译)057:FastCGI编译(Windows、Linux、MacOS环境下编译)

文章目录 1、FastCGI介绍2、FastCGI下载3、Windows下编译4、linux下编译5、MacOS下编译1、FastCGI介绍 FCGI 是 FastCGI 的缩写,是一种用于改善 CGI(Common Gateway Interface)性能的协议。在传统的 CGI 中,每次请求都需要启动一个新的进程来处理,这导致了较高的资源消耗和…...

jenkins+newman+postman持续集成环境搭建

一、Newman简介 Newman是一款基于Node.js开发的&#xff0c;可以运用postman工具直接从命令运行和测试postman集合 二、Newman应用 环境准备&#xff1a;js/ cnpm或npm配置好环境&#xff0c;执行如下命令 三、安装newman 验证是否安装成功&#xff0c;命令&#xff1a;newm…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...