vector

vector

string的流提取

代码如下:

C++ 复制代码
istream& operator>>(istream& is, string& str)
{
	str.clear();
	int i = 0;
	char buff[256];

	char ch;
	//is >> ch;
	ch = is.get();
	while (ch != ' ' && ch != '\n')
	{
		//str += ch;
		buff[i++] = ch;
		if (i == 255)//255个字符
		{
			buff[255] = '\0';//最后一个留给'\0'
			str += buff;
			i = 0;//置为零重新提取
		}
		ch = is.get();
	}
	if (i > 0)//不满255
	{
		buff[i] = '\0';
		str += buff;
	}
	return is;
}

这里引入buff,在栈区开辟空间

有两个好处:

1.栈上开辟空间,比堆效率高

2.即用即销毁

总的来说,对于大的方面来说,减少扩容,不会浪费空间

用getline的情况:

string.h

C++ 复制代码
istream& getline(istream& is, string& str, char delim = '\n');
//delim是分隔符

string.cpp

C++ 复制代码
istream& getline(istream& is, string& str, char delim)
	{
		str.clear();

		int i = 0;
		char buff[256];

		char ch;
		ch = is.get();
		while (ch != delim)
		{
			// 放到buff
			buff[i++] = ch;
			if (i == 255)
			{
				buff[i] = '\0';
				str += buff;
				i = 0;
			}

			ch = is.get();
		}

		if (i > 0)
		{
			buff[i] = '\0';
			str += buff;
		}

		return is;
	}

test.cpp

C++ 复制代码
void test_string07()
{
	Tzuyu::string s1;
	getline(cin, s1);
	cout << s1 << endl;
	getline(cin, s1, '#');//遇到#停止输入
	cout << s1 << endl;
}

swap

库里面的swap

会进行深拷贝,深拷贝会重新拷贝一块空间,进行赋值,再析构销毁,但是这样的代价太大了

怎么样能使代价变小呢?

这个时候我们可以用string自己的成员函数swap

string自己的成员函数swap

现代写法

拷贝的现代写法

代码如下:

c++ 复制代码
//现代写法
string::string(const string& s)
{
	string tmp(s._str);
	swap(tmp);
}

这种写法,有点类似于资本主义压榨剩余价值,让别人来干活,传统的写法就是老老实实地开辟空间进行深拷贝,现代写法的逻辑图如下:

这里的swap是string成员里面的swap

所有的值都必须要走初始化列表

为什么这里的tmp要指向空呢?

因为这里是局部对象,出了作用域要被操作系统给回收的,索性直接置空

赋值的现代方法

C++ 复制代码
string& string::operator=(const string& s)
{
	if (this != &s)
	{
		string tmp(s._str);
		swap(tmp);
	}
	return *this;
}

更加简便地写法:

string.h

C++ 复制代码
string& operator=(string s);

string.cpp

C++ 复制代码
string& string::operator=( string s)
{
	swap(s);
	return *this;
}

这里是让s和s1交换空间,因为在栈区,所以会被操作系统回收空间

这里并没有效率的提升,本质是复用

引用计数+写时拷贝(了解)

写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。

引用计数:用来记录资源使用者的个数。在构造时,将资源的计数给成1,每增加一个对象使用该 资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源, 如果计数为1,说明该对象时资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有 其他对象在使用该资源。

vector

实现代码:

C++ 复制代码
#include<vector>

int main()
{
	vector<int> v1;
	vector<int> v2(10, 1);
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

	// 遍历
	for (size_t i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;

	vector<int>::iterator it1 = v1.begin();
	while (it1 != v1.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<string> vstr;//不带'\0'
	string s1 = "张三";//带'\0'
	vstr.push_back(s1);
	vstr.push_back("李四");

	for (const auto& e : vstr)
	{
		cout << e << " ";
	}
	cout << endl;

	vstr[0] += 'x';
	vstr[0] += "apple";
	//vstr[0][0]++;
	vstr[0][1]++;
	vstr[0][1]++;
	vstr.operator[](0).operator[](1)++;//看上去像二维数组,实际上调用了两个容器,先是vector后是string

	for (const auto& e : vstr)
	{
		cout << e << " ";
	}
	cout << endl;
相关推荐
菜鸟~noob23313 分钟前
【电子战】 第09篇:阵列信号处理——波束形成、MVDR、MUSIC【含matlab代码】
开发语言·matlab·信号处理
ocean210322 分钟前
2025-2026年Python面试高频知识点洞察
开发语言·python·面试·python八股文
零依赖极客37 分钟前
Day 6·1 ARMv8.2 dotprod——vdotq_s32 一条指令做 4 个点积
c语言·开发语言·人工智能·矩阵·arm·vllm
stolentime43 分钟前
洛谷P10515 转圈题解
c++·算法·数学建模·贪心算法
和裕2 小时前
蜂窝板 vs 七层瓦楞重型纸箱:大件工业设备运输性能与成本全对比
大数据·运维·网络·人工智能·算法
衡石科技2 小时前
Data_Agent记忆机制与经验复用衡石分析智能体会话记忆与长期学习技术解析
人工智能·科技·学习·算法·企业级bi
新时代牛马2 小时前
cyclictest 毛刺从哪来?从ftrace、latencytop、perf到IRQ/调度延迟定位
android·开发语言·python·kotlin
三8442 小时前
Java 模板注入(FreeMarker) · 02 · 模板引擎与 FreeMarker 语法
java·开发语言·web安全·freemarker
IvanCodes3 小时前
Python 基础语法(七):推导式与常见遍历写法
开发语言·python
暮雨哀尘3 小时前
Java 基础练习(一):创建类并调用对象
java·开发语言