【C++】—— string模拟实现

前言:

        学习了string的使用,总感觉了解不是很深厚;自己模拟实现string类来帮助自己理解。

        这里只是实现了一部分内容(并没有实现完整的string类)。

先来实现string类里面的成员变量:

#include<iostream>
namespace HL
{class string{public:private:char* _str;size_t _size;size_t _capacity;const static size_t npos;};const size_t HL::string::npos = -1;
}

一、string默认成员函数(构造、析构、赋值运算符重载)

        1.1、构造函数

1> 默认构造

        默认构造函数就是不需要传参的构造函数;这里实现就开辟一个字符的空间存放 '\0'即可(_capacity不包括 '\0' )。

string(){_str = new char[1];_str[0] = '\0';_size = 0;_capacity = 0;}

2> 拷贝构造

        拷贝构造,在实现时需要注意:是深拷贝,而不是浅拷贝(值拷贝)。

深拷贝(深拷贝简单来说就是,要开辟一块新的空间,把原空间里的值拷贝到新的空间里)。

		string(const string& str){_str = new char[str._capacity + 1];memcpy(_str, str._str, str._size + 1);_size = str._size;_capacity = str._capacity;}

3> 其他构造

        其他构造函数就有很多了,这里就实现以下这几个:

        string (const char* s);

		string(const char* s){size_t len = strlen(s);_str = new char[len + 1];memcpy(_str, s, len + 1);_size = len;_capacity = len;}

        string (const char* s, size_t n);

		string(const char* s, size_t n){size_t len = strlen(s);if (n > len){n = len;}_str = new char[n + 1];memcpy(_str, s, n);_str[n] = '\0';_size = n;_capacity = n;}

        string (size_t n, char c);

		string(size_t n, char c){_str = new char[n + 1];for (size_t i = 0; i < n; i++){_str[i] = c;}_str[n] = '\0';_size = n;_capacity = n;}

        1.2、析构函数

        析构函数比较简单,释放开辟的资源即可;

		~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}

        1.3、赋值运算符重载     

        赋值运算符有3个重载,这里就一一实现:

        string& operator= (const string& str );

实现这个有很多种方法,

        可以释放原空间,再开辟新的空间,将数据拷贝到新的空间中去

		string& operator=(const string& str){delete[] _str;_str = new char[str._capacity];memcpy(_str, str._str, str._size + 1);_size = str._size;_capacity = str._capacity;return *this;}

可以调用拷贝构造,构造一个tmp、再将tmp与*this 中的值进行交换(要实现交换函数)

template <typename T>
void Swap(T& x, T& y)
{T tmp = x;x = y;y = tmp;
}
string& operator= (const string& str)
{string tmp(str);Swap(_str, tmp._str);Swap(_size, tmp._size);Swap(_capacity, tmp._capacity);return *this;
}

这里如果已经实现string类swap成员函数,就可以直接调用。

        string& operator= (const char* s );        

		/*string& operator= (const char* s){size_t len = strlen(s);delete[] _str;_str = new char[len + 1];memcpy(_str, s, len + 1);_size = _capacity = len;return *this;}*/string& operator= (const char* s){string tmp(s);Swap(_str, tmp._str);Swap(_size, tmp._size);Swap(_capacity, tmp._capacity);return *this;}

        string& operator= (char c );

		string& operator= (char c){delete[] _str;_str = new char[2];_str[0] = c;_str[1] = '\0';_size = _capacity = 1;return *this;}

二、元素访问与迭代器

        2.1、迭代器

        迭代器,虽然在string类中使用的不是很多,但在后面的容器中有大用处。

        (在string类中就可以简单的理解成指针)。

		//迭代器typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return (_str + _size);}const_iterator begin() const{return _str;}const_iterator end() const{return (_str + _size);}

        实现了迭代器之后,范围for这个语法糖就可以使用了(底层就是迭代器)。        

        2.2、下标访问元素

        实现下标访问,就是 [ ]运算符重载。

		//下标访问 [ ]char& operator[] (size_t pos){assert(pos >= _size);return *(_str + pos);}const char& operator[] (size_t pos) const{assert(pos >= _size);return *(_str + _size);}

        at函数和 [ ] 运算符重载原理一样,这里就不重复写了。

三、增删查改

        在实现增之前,要先实现一个函数,就是调整空间大小的(扩容来用)。

		//扩容void reserve(size_t n){if (n > _capacity){char* s = new char[n + 1];memcpy(s, _str, _size);delete[] _str;_str = s;_capacity = n;}}


        增删这里就实现这些成员函数。

        1、push_back  、append 、operator+=

append重载比较多,这里就实现其中的几个。

		//扩容void reserve(size_t n){if (n > _capacity){char* s = new char[n + 1];memcpy(s, _str, _size);delete[] _str;_str = s;_capacity = n;}}//增void push_back(char c){if (_size >= _capacity){reserve((_capacity == 0) ? 4 : 2 * _capacity);}_str[_size] = c;_size++;_str[_size] = '\0';}void append(const string& str){size_t n = _size + str._size;if (n > _capacity){reserve(n);}for (int i = 0; i < str._size; i++){_str[_size + i] = str._str[i];}_size += str._size;_str[_size] = '\0';}void append(const char* s){size_t len = strlen(s);int n = _size + len;if (n > _capacity){reserve(n);}for (int i = 0; i < len; i++){_str[_size + i] = s[i];}_size = n;_str[_size] = '\0';}void append(size_t n, char c){if (_size + n > _capacity){reserve(_size + n);}for (int i = 0; i < n; i++){_str[_size + i] = c;}_size += n;_str[_size] = '\0';}string& operator+=(const string& str){this->append(str);return *this;}string& operator+=(const char* s){this->append(s);return *this;}string& operator+=(char c){this->push_back(c);return *this;}

        2、insert、erase

        insert重载也比较多,比较冗余;这里也只实现其中的一部分;

        erase这里只实现一个

//insert 、erase
void insert(size_t pos, const string& str)
{assert(pos >= 0 && pos < _size);size_t len = str._size;size_t n = _size + len;if (n > _capacity){reserve(n);}//挪动数据for (size_t i = n; i >= pos + len; i--){_str[i] = _str[i - len];}memcpy(_str + pos, str._str, str._size);_size += str._size;_str[_size] = '\0';
}
void insert(size_t pos, const char* s)
{assert(pos >= 0 && pos < _size);size_t len = strlen(s);size_t n = _size + len;if (n > _capacity){reserve(n);}//挪动数据for (size_t i = n; i >= pos + len; i--){_str[i] = _str[i - len];}memcpy(_str + pos, s, len);_size += len;_str[_size] = '\0';
}
void insert(size_t pos, size_t n, char c)
{assert(pos >= 0 && pos < _size);if (_size + n > _capacity){reserve(_size + n);}//挪动数据for (size_t i = _size+n; i >= pos + n; i--){_str[i] = _str[i - n];}for (size_t i = 0; i < n; i++){_str[pos + i] = c;}_size += n;_str[_size] = '\0';
}
void erase(size_t pos, size_t len = npos)
{assert(pos >= 0 && pos < _size);if (len == npos){_str[0] = '\0';_size = 0;return;}for (size_t i = pos; (len + i) < _size; i++){_str[i] = _str[i + len];}_size -= len;_str[_size] = '\0';
}

        3、find

		//findsize_t find(const string& str, size_t pos = 0){assert(pos >= 0 && pos < _size);char* tmp = strstr(_str + pos, str._str);if (tmp == nullptr){return -1;}return tmp - _str;}size_t find(const char* s, size_t pos = 0){assert(pos >= 0 && pos < _size);char* tmp = strstr(_str + pos, s);if (tmp == nullptr){return -1;}return tmp - _str;}size_t find(char c, size_t pos = 0){assert(pos >= 0 && pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == c){return i;}}return -1;}

        4、swap

        swap作为string的成员函数,交换两个string类类型的对象。

		//swapvoid swap(string& str){Swap(_str, str._str);Swap(_size, str._size);Swap(_capacity, str._capacity);}

        这里swap函数内部也可以调用库里面的swap模版(这里我自己写了一个模版Swap)

有了swap函数,上面赋值运算符重载中就可以这样写了:

		string& operator= (const string& str){string tmp(str);swap(tmp);return *this;}

四、字符串操作函数

        1、c_str

        c_str()函数返回string类对象中的字符串;

const char* c_str() const
{return _str;
}	
char* c_str()
{return _str;
}

        2、substr

        获得,sting对象中字符串的子串。

//substr
string substr(size_t pos = 0, size_t len = npos) const
{assert(pos >= 0 && pos < _size);size_t n = 0;if (len == npos || pos + len > _size){n = _size - pos;}else{n = len;}string ret;for (size_t i = 0; i < n; i++){ret += _str[pos + i];}return ret;
}

五、其他成员函数

        

        这里max_size是返回容器可以容纳的最大元素的数量,这里就不进行实现了。

reserve在增加元素前已经实现了。(扩容)

//其他成员函数
size_t size() const
{return _size;
}
size_t length()const
{return _size;
}
size_t capacity()const
{return _capacity;
}
void clear()
{_str[0] = '\0';_size = 0;
}
bool empty()const
{return _size == 0;
}
void resize(size_t n)
{if (n > _capacity){reserve(n);}_size = n;_str[_size] = '\0';
}
void resize(size_t n, char c)
{if (n > _capacity){reserve(n);}for (size_t i = _size; i < n; i++){_str[i] = c;}_size = n;_str[_size] = '\0';
}

        

六、流插入、流提取

        因为成员函数有一个隐藏的this指针,会和istream 和istream 类对象抢占第一个参数的位置,所以我们不能将流插入和流提取写成string类的成员函数。

        string中实现了访问元素方成员函数,就可以不将流插入、流提取写成string类的友元函数。

        1、流插入运算符重载

	std::ostream& operator<<(std::ostream& out, const HL::string& str){//for (int i = 0; i < str.size(); i++)//{//	out << str[i];//}//return out;for (auto ch : str){out << ch;}return out;}

        2、流提取运算符重载

        1、 s.clear()清理缓冲区(上次cin流提取的剩余);

        2、 创建一个数组,防止多次去开空间(输入到128或者输入结束(‘ ’或者‘\n’)才添加到str中)。

        3、下面的代码处理缓冲区的空格。

        char ch;
        ch = in.get();
        while (ch == ' ' || ch == '\n')
        {
            ch = in.get();
        }

        4、最后循环里if是遇到空格或者换行结束,将s中输入添加到s中,末尾添加'\0'。

       

std::istream& operator>>(std::istream& in, HL::string& str)
{char s[128] = { 0 };char ch;ch = in.get();while (ch == ' ' || ch == '\n'){ch = in.get();}str.clear();int i = 0;while (ch != '\n'){s[i] = ch;i++;if (i == 127){s[i] = '\0';str += s;i = 0;}ch = in.get();}if (i){str += s;}return in;
}

HL :: string 源码
 

#pragma once
#include<iostream>
#include<cassert>template <typename T>
void Swap(T& x, T& y)
{T tmp = x;x = y;y = tmp;
}
namespace HL
{class string{friend std::ostream& operator<<(std::ostream& out, const HL::string& str);friend std::istream& operator>>(std::istream& in, HL::string& str);public://构造函数/*string(){_str = new char[1];_str[0] = '\0';_size = 0;_capacity = 0;}string(char ch){_str = new char[1];_str[0] = ch;_size = 0;_capacity = 0;}*/string(char ch = '\0'){_str = new char[2];_str[0] = ch;_str[1] = '\0';_size = 1;_capacity = 1;}string(const char* s){size_t len = strlen(s);_str = new char[len + 1];memcpy(_str, s, len + 1);_size = len;_capacity = len;}string(const char* s, size_t n){size_t len = strlen(s);if (n > len){n = len;}_str = new char[n + 1];memcpy(_str, s, n);_str[n] = '\0';_size = n;_capacity = n;}string(const string& str){_str = new char[str._capacity + 1];memcpy(_str, str._str, str._size + 1);_size = str._size;_capacity = str._capacity;}string(size_t n, char c){_str = new char[n + 1];for (size_t i = 0; i < n; i++){_str[i] = c;}_str[n] = '\0';_size = n;_capacity = n;}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}/*string& operator=(const string& str){delete[] _str;_str = new char[str._capacity];memcpy(_str, str._str, str._size + 1);_size = str._size;_capacity = str._capacity;return *this;}*//*string& operator= (const string& str){string tmp(str);Swap(_str, tmp._str);Swap(_size, tmp._size);Swap(_capacity, tmp._capacity);return *this;}*/string& operator= (const string& str){string tmp(str);swap(tmp);return *this;}/*string& operator= (const char* s){size_t len = strlen(s);delete[] _str;_str = new char[len + 1];memcpy(_str, s, len + 1);_size = _capacity = len;return *this;}*/string& operator= (const char* s){string tmp(s);Swap(_str, tmp._str);Swap(_size, tmp._size);Swap(_capacity, tmp._capacity);return *this;}string& operator= (char c){delete[] _str;_str = new char[2];_str[0] = c;_str[1] = '\0';_size = _capacity = 1;return *this;}//string& operator= (char c)//{//	string tmp(c);//	Swap(_str, tmp._str);//	Swap(_size, tmp._size);//	Swap(_capacity, tmp._capacity);//	return *this;//}//迭代器typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return (_str + _size);}const_iterator begin() const{return _str;}const_iterator end() const{return (_str + _size);}//下标访问 [ ]char& operator[] (size_t pos){assert(pos >= 0 && pos < _size);return *(_str + pos);}const char& operator[] (size_t pos) const{assert(pos >= 0 && pos < _size);return *(_str + _size);}//扩容void reserve(size_t n){if (n > _capacity){char* s = new char[n + 1];memcpy(s, _str, _size);delete[] _str;_str = s;_capacity = n;}}//增void push_back(char c){if (_size >= _capacity){reserve((_capacity == 0) ? 4 : 2 * _capacity);}_str[_size] = c;_size++;_str[_size] = '\0';}void append(const string& str){size_t n = _size + str._size;if (n > _capacity){reserve(n);}for (int i = 0; i < str._size; i++){_str[_size + i] = str._str[i];}_size += str._size;_str[_size] = '\0';}void append(const char* s){size_t len = strlen(s);size_t n = _size + len;if (n > _capacity){reserve(n);}for (int i = 0; i < len; i++){_str[_size + i] = s[i];}_size = n;_str[_size] = '\0';}void append(size_t n, char c){if (_size + n > _capacity){reserve(_size + n);}for (int i = 0; i < n; i++){_str[_size + i] = c;}_size += n;_str[_size] = '\0';}string& operator+=(const string& str){this->append(str);return *this;}string& operator+=(const char* s){this->append(s);return *this;}string& operator+=(char c){this->push_back(c);return *this;}//insert 、erasevoid insert(size_t pos, const string& str){assert(pos >= 0 && pos < _size);size_t len = str._size;size_t n = _size + len;if (n > _capacity){reserve(n);}//挪动数据for (size_t i = n; i >= pos + len; i--){_str[i] = _str[i - len];}memcpy(_str + pos, str._str, str._size);_size += str._size;_str[_size] = '\0';}void insert(size_t pos, const char* s){assert(pos >= 0 && pos < _size);size_t len = strlen(s);size_t n = _size + len;if (n > _capacity){reserve(n);}//挪动数据for (size_t i = n; i >= pos + len; i--){_str[i] = _str[i - len];}memcpy(_str + pos, s, len);_size += len;_str[_size] = '\0';}void insert(size_t pos, size_t n, char c){assert(pos >= 0 && pos < _size);if (_size + n > _capacity){reserve(_size + n);}//挪动数据for (size_t i = _size+n; i >= pos + n; i--){_str[i] = _str[i - n];}for (size_t i = 0; i < n; i++){_str[pos + i] = c;}_size += n;_str[_size] = '\0';}void erase(size_t pos, size_t len = npos){assert(pos >= 0 && pos < _size);if (len == npos){_str[0] = '\0';_size = 0;return;}for (size_t i = pos; (len + i) < _size; i++){_str[i] = _str[i + len];}_size -= len;_str[_size] = '\0';}//findsize_t find(const string& str, size_t pos = 0){assert(pos >= 0 && pos < _size);char* tmp = strstr(_str + pos, str._str);if (tmp == nullptr){return -1;}return tmp - _str;}size_t find(const char* s, size_t pos = 0){assert(pos >= 0 && pos < _size);char* tmp = strstr(_str + pos, s);if (tmp == nullptr){return -1;}return tmp - _str;}size_t find(char c, size_t pos = 0){assert(pos >= 0 && pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == c){return i;}}return -1;}//swapvoid swap(string& str){Swap(_str, str._str);Swap(_size, str._size);Swap(_capacity, str._capacity);}//c_strconst char* c_str() const{return _str;}	char* c_str(){return _str;}//substrstring substr(size_t pos = 0, size_t len = npos) const{assert(pos >= 0 && pos < _size);size_t n = 0;if (len == npos || pos + len > _size){n = _size - pos;}else{n = len;}string ret;for (size_t i = 0; i < n; i++){ret += _str[pos + i];}return ret;}//其他成员函数size_t size() const{return _size;}size_t length()const{return _size;}size_t capacity()const{return _capacity;}void clear(){_str[0] = '\0';_size = 0;}bool empty()const{return _size == 0;}void resize(size_t n){if (n > _capacity){reserve(n);}_size = n;_str[_size] = '\0';}void resize(size_t n, char c){if (n > _capacity){reserve(n);}for (size_t i = _size; i < n; i++){_str[i] = c;}_size = n;_str[_size] = '\0';}private:char* _str;size_t _size;size_t _capacity;const static size_t npos;};const size_t HL::string::npos = -1;std::ostream& operator<<(std::ostream& out, const HL::string& str){//for (int i = 0; i < str.size(); i++)//{//	out << str[i];//}//return out;for (auto ch : str){out << ch;}return out;}std::istream& operator>>(std::istream& in, HL::string& str){char s[128] = { 0 };char ch;ch = in.get();while (ch == ' ' || ch == '\n'){ch = in.get();}str.clear();int i = 0;while (ch != '\n'){s[i] = ch;i++;if (i == 127){s[i] = '\0';str += s;i = 0;}ch = in.get();}if (i){str += s;}return in;}
};

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

草莓团队创造了o1 - Building OpenAI o1 (Extended Cut) 观后笔记

美妙的事物往往需要世界去创造&#xff0c;商业希望大模型越来越快给出回答。或许花费几个月几年的时间持续思考&#xff0c;大模型能够解决更复杂的问题&#xff0c;而不只是回答42 刚发现凌晨OpenAI发布了一个22多分钟的采访&#xff0c;将构建出O1的整个团队拉到一个小屋子&…

让Tkinter更美观:教你同步Tkinter窗口与弹窗图标(Tkinter同步主窗口与Messagebox的图标)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 步骤1:主窗口图标📝 步骤2:messagebox 图标📝 示例代码📝 实现原理与代码解释⚓️ 相关链接 ⚓️📖 介绍 📖 你有没有注意到,在开发软件图形界面时,会需要弹出一些提示框,而这些提示框的图标总…

695. 岛屿的最大面积

思路&#xff1a; 只有当前是陆地&#xff0c;才会构成岛屿 当前是陆地&#xff0c;进入回溯 往当前的上、下、左、右位置分别找陆地位置&#xff0c;为陆地 1>标记为2:代表已经遍历过的陆地 2>记录当前方向的陆地总数 以当前陆地组成的岛屿面积当前陆地面积向上的…

11----mtk芯片专用解锁工具 解除FRP 很小的工具 去除屏幕锁 免授权等等 工具预览与步骤解析

机型的FRP锁是谷歌账号锁。工具是mtk芯片使用 。可以去除当前机型的FRP和米账号重置。操作非常简单。但前提是联机驱动要装好。任何的工具联机驱动是关键。 工具功能选项 ★★★★★工具开发者说明功能与选项操作与资源下载 ★★★★★具体工具操作使用指南 工具联机界面与…

Type-C协议(CC检测原理)-CC1和CC2接电阻-数字和模拟耳机兼容

Type-C协议&#xff08;CC检测原理&#xff09;-CC1和CC2接电阻-数字和模拟耳机兼容 - Sean_hn - 博客园 (cnblogs.com)

4.变量与函数

作业系统链接 变量是Python中用于存储数据的命名标签&#xff0c;通过赋值&#xff0c;新值可以覆盖旧值&#xff0c;且数据类型不必相同。变量命名规则包括必须以字母或下划线开头&#xff0c;由字母、数字和下划线组成&#xff0c;大小写敏感&#xff0c;并避免使用保留字。函…

精选写作技巧!分享4款ai写毕业论文可以写出公式表格的软件

在撰写毕业论文时&#xff0c;AI写作工具可以极大地提高效率和质量。以下是四款值得推荐的AI软件&#xff0c;它们不仅能够帮助生成高质量的论文初稿&#xff0c;还能处理公式和表格等复杂内容。 传送门&#xff1a;https://www.aipaperpass.com?piclLGw 千笔-AIPassPaper是一…

Rx Strategist:智能体实现处方验证的方方面面,如适应症、剂量、药物相互作用

Rx Strategist&#xff1a;智能体实现处方验证的方方面面&#xff0c;如适应症、剂量、药物相互作用 秒懂大纲提出背景&#xff1a;拆解解法分析全流程分析创意 秒懂大纲 ├── 处方验证系统【主题】 │ ├── 背景和问题【问题描述】 │ │ ├── 现代药物复杂性对严…

2024年华为杯研究生数学建模竞赛研赛C题超详细解题思路+数据预处理代码分享

研赛题目由当年负责赛区【23年为东南大学&#xff0c;24年为山东大学】的相关老师每年独立命题&#xff0c;因此每年的题目在涉及的模型和知识点上都有很大差异。数模竞赛是百分比获奖&#xff0c;选择人数最多的也就意味着题目简单&#xff0c;会有很多新手、小白选择。我们只…

python有main函数吗

python和C/Java不一样&#xff0c;没有主函数一说&#xff0c;也就是说python语句执行不是从所谓的主函数main开始的。 当运行单个python文件时&#xff0c;如运行a.py&#xff0c;这个时候a的一个属性__name__是__main__。 当调用某个python文件时&#xff0c;如b.py调用a.p…

华为HarmonyOS地图服务 13 - 如何实现地图数据聚合效果?

场景介绍 本章节将向您介绍如何根据地图数据实现聚合效果。 您可以通过比例尺缩放自适应聚合效果,聚合图标可点击。聚合支持功能: 支持按距离聚合ClusterItem。支持绘制聚合Overlay的默认图标。支持绘制聚合Overlay的自定义图标。支持监听聚合Overlay的点击事件。支持添加单…

华为为什么要做三折叠屏手机?

前些天我做了一条视频&#xff0c;关于讲华W的新的三折叠屏手机。我说我有点失望&#xff0c;结果引起了华W的同事的一些关注。于是&#xff0c;华W几位高管都跑过来&#xff0c;跟我解释为什么会出现这样的一个状态。 我才知道&#xff0c;这款手机他们其实是亏着钱在卖的。因…

云盘视频保护神器,支持云盘视频加密与在线播放,配合alist使用,超完美!

平时我们保护视频&#xff0c;一般都是采用压缩工具&#xff0c;进行加密打包&#xff0c;然后在上传到网盘存储。这虽然能起到很好的保护&#xff0c;但是有很多问题&#xff1f;比如&#xff1a;无法直接在线播放&#xff0c;还得从网盘中下载后解压&#xff0c;才能进行观看…

【shell脚本1】Shell脚本学习--入门

目录 简介 Hello World 注释 打印输出 简介 Shell是一种脚本语言&#xff0c;那么&#xff0c;就必须有解释器来执行这些脚本。 Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等&#xff0c;习惯上把它们称作一种Shell。我们常说有多少种Shell&#xff0c;其实说的…

ProtoBuf序列化框架介绍

文章目录 ProtoBuf介绍使用流程 QUICK START创建.proto文件注释语法编译部分代码展示使用接口运行结果 ProtoBuf介绍 ProtoBuf全称是Protocol Buffer&#xff0c;是一个数据结构的序列化和反序列化框架 他又很多好处&#xff0c;首先是他支持跨平台&#xff0c;支持Java、C、…

进程间通信的七种方法实战演示!值得收藏!

文章目录 前言一、管道&#xff08;Pipes&#xff09;管道示例代码&#xff1a;管道示例流程解读&#xff1a;管道示例运行效果&#xff1a; 二、消息队列&#xff08;Message Queues&#xff09;消息队列示例代码消息队列示例流程解读&#xff1a;消息队列示例执行效果 三、共…

分析redis实现分布式锁的思路

文章目录 1、基于redis实现分布式锁&#xff1a;利用key的唯一性1.1、独占排他1.2、死锁问题1.2.1、redis客户端程序获取了锁之后&#xff0c;服务器立马宕机&#xff0c;就会导致死锁。1.2.2、不可重入&#xff1a;可重入 1.3、原子性&#xff1a;加锁和过期之间&#xff1a;s…

【JavaEE】——线程的安全问题和解决方式

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c;你们的点赞收藏是我前进最大的动力&#xff01;&#xff01;希望本文内容能够帮助到你&#xff01; 目录 一&#xff1a;问题引入 二&#xff1a;问题深入 1&#xff1a;举例说明 2&#xff1a;图解双线程计算…

springboot数字化超市管理系统—计算机毕业设计源码34804

摘 要 在网络信息的时代&#xff0c;众多的软件被开发出来&#xff0c;给用户带来了很大的选择余地&#xff0c;而且人们越来越追求更个性的需求。在这种时代背景下&#xff0c;超市只能以用户为导向&#xff0c;按品种小批量组织生产&#xff0c;以产品的持续创新作为超市最重…

ONES 与华为云深度合作,共同打造企业智能研发管理平台

9月20日&#xff0c;在华为全联接大会&#xff08;HUAWEI CONNECT 2024&#xff09;上&#xff0c;深圳复临科技有限公司&#xff08;以下简称“ONES”&#xff09;与华为云计算技术有限公司&#xff08;以下简称“华为云”&#xff09;正式签署合作协议&#xff0c;双方将在企…