C++初阶 —— string类

模拟string(一)详解 这个顺序是不可以的,因为初始化列表的初始化顺序不是按实例化的顺序,而是按照声明的顺序初始化,这样就会导致_str在初始化的时候size为随机值,所以建议实例化顺序和声明顺序一致。所以当结束后会先对s1析构,然后再对s2析构,但是因为s1和s2都指向同一块空间,导致这块空间析构两次,并且对s1进行修改数据的同时s2也会被修改。如果将缺省值改成string(const char* str=‘\0’)也会报错,因为\0是一个字符,将字符传给char *是不可以的。通过调试我们可以看到s1和s2的地址是一样的。 阅读详情

目录

一,标准库中的string类

二,string类的常用接口

构造函数

容量操作函数

访问及遍历操作函数

修改操作函数

非成员函数(即全局函数)

三,深/浅拷贝

经典string类问题

浅拷贝

深拷贝

写时拷贝(了解)

四,string类的模拟实现


        C语言中,字符串是以“\0”结尾的字符集合;C标准库提供了一些str库函数,但库函数与字符串是分开的,不符合OOP思想,且底层空间需要用户自己管理,容易越界访问;

注:编码格式,ASCII、UTF-8/16/32等;

一,标准库中的string类

string类

  • string是利用动态数组实现的,是在堆上开辟的空间;
  • string类是基于basic_string类模板的一个实例,使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数;
  • string是标准的字符串类,其接口类似于标准字符容器的接口;提供了一系列成员函数和操作符函数,用于对字符串进行赋值、比较、查询、修改等操作;
  • 不能操作多字节或变长字符的序列;

注:在使用string类时,必须包含#include<string>头文件,其命名空间为std;

二,string类的常用接口

构造函数

  • string(),构造空的string类对象,即空字符串;
  • string(const string&s),拷贝构造函数;
  • string(const char*s),用C-string来构造string类对象;
  • string(size_t n, char c),string类对象中包含n个字符c;
int main()
{
    char s[] = "abc";
    string str1; //(1)默认无参数构造
    string str2(s); //(4)复制以空结尾的字符序列(C字符串),类似string str2=s; 
    string str5(s, 2); //(5)复制字符串子串   
    string str3(str2); //(2)拷贝构造,即复制,或string str3=str2;
    string str4(str2, 2); //(3)复制string类子串    
    string str6(5, 'a'); //(6)填充5个连续的a
    string str7(str2.begin(), str2.end()); //(7)迭代器构造[begin,end)

    string str8("abc");
    string str9 = "abc"; //字符串字面量初始化,调用(4)类型构造函数(应先转换一临时对象在拷贝,编译器优化为直接构造,可使用explicit避免隐式类型转换)
    string str10{ 'a','b','c' }; //(8)C++11引入的列表初始化,或string str10={'a','b','c'};    
    string str11 = move(str10); //(9)C++11移动构造;
}

容量操作函数

size返回字符串有效字符长度,底层实现原理完全相同,引入size()的原因是与其他容器的接口保持一致,一般基本都使用size();
length
capacity返回空间总大小;
reserve为字符串预留空间,对成员变量capacity操作;
resize将有效字符的个数改成n个,多出的空间用字符c填充,对成员变量size操作;
resize(size_t n),resize(size_t n, char c)都是将字符串中有效字符个数改变为n个,不同的是当字符个数增多时,前者用0来填充,后者用字符c来填充;
resize改变元素个数时,增多可能会改变底层容量的大小,减少空间大小不变(vs/g++);
empty检测字符串是否为空串,是true,否false;
clear清空有效字符,size为0,capacity不变;
只是将string中有效字符清空,不改变底层空间大小;
int main()
{
	string s("abcd");
	cout << s.size() << endl;
	cout << s.length() << endl;

	s.resize(6);
	cout << s.size() << endl;
	s.resize(10, 'c');
	cout << s << endl;

	s.reserve(20);
	cout << s.capacity() << endl;
}

访问及遍历操作函数

operator[ ]返回pos位置的字符,重载运算符[ ],无边界检查比at快;
at返回pos位置的字符,但会边界检查,超出会抛异常;
begin+endbegin获取第一个字符的迭代器,
end获取最后一个字符下一个位置的迭代器;
rbegin+rendrbegin获取反向第一个字符的迭代器,
rend获取反向最后一个字符下一个位置的迭代器;
范围forC++11支持更简洁范围for的新遍历方式,支持迭代器就支持范围for;
int main()
{
	string s("abcdefg");
	for (int i = 0; i < s.size(); i++)
	{
		cout << s[i];
	}
	cout << endl;

	//迭代器遍历
	//string::iterator it = s.begin();
	auto it1 = s.begin();
	while (it1 != s.end())
	{
		cout << *it1;
		it1++;
	}
	cout << endl;

	//反向遍历
	auto it2 = s.rbegin();
	while (it2 != s.rend())
	{
		cout << *it2;
		it2++;
	}
	cout << endl;

	//范围for遍历
	for (auto i:s)
	{
		cout << i;
	}
	return 0;
}

修改操作函数

push_back尾插单个字符c;
append追加字符串;
assign赋新值以替代当前值;
operator+=追加字符串或单个字符;
c_str返回c格式字符串('\0'结尾)指针,const指针;
substr在str中从pos位置开始,截取n个字符,并返回新对象;
insert插入字符串或单个字符,少用,需挪动数据;
replace替换字符串;
swap交换字符串值;
erase删除指定位置后的字符,npos(无符号-1,即最大值),也少用;
find从字符串pos位置开始往后找字符c,返回该字符第一个位置;
或查找字符串;
rfind从字符串pos位置开始往后找字符c,返回该字符最后一个位置;
或查找字符串;
int main()
{
	string s("abc");
	s.push_back('d');
	s.append("efg");
	s += "hijk";
	cout << s.c_str() << endl;
	cout << s.find('c') << endl;
	cout << s.find("hij", 2) << endl; 
	cout << s.substr(2, 3) << endl;
	cout << s.insert(0, "ab") << endl;
	s.reserve(20);
	cout << s.erase() << endl; //size为0,capacity不变,类似clear
	return 0;
}

非成员函数(即全局函数)

operator+尽量少用,因传值返回导致深拷贝效率低;
operator>>输入运算符重载;
operator<<输出运算符重载;
getline获取一行字符串;
relational operators(<、>、=...)大小比较;
int main()
{
	string s1;
	cin >> s1;
	cout << s1 << endl;
	getline(cin, s1);

	string s2 = "abcd";
	getline(cin, s2); //会清除和覆盖之前内容
	cout << s2 << endl;
	return 0;
}

注:

  • npos类静态成员变量,值为无符号-1,string::npos;
  • vs编译器string类大小(即sizeof)为28, 因为默认有个buff数组(char _buf[16]),所以12+16;
  • g++编译器string类大小(即sizeof)为8;

三,深/浅拷贝

经典string类问题

  • s1调用默认拷贝构造,会导致是s1、s2共用同一块空间;
  • 在释放时,会对同一块空间释放两次引起程序崩溃;
#include <iostream>
#include <assert.h>

class string
{
public:
	//构造函数
	string(const char* str = "")
	{
        if(nullptr == str)
        {
            assert(false);
            return;
        }
        _str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}

	//析构函数
	~string()
	{
        if(_str)
        {
            delete[] _str;
		    _str = nullptr;
        }
	}
private:
	char* _str;
};

int main()
{
	string s1("abcd");
	string s2(s1); //调用默认拷贝构造,值拷贝或浅拷贝
	return 0;
}

浅拷贝

  • 又称位拷贝,编译器会直接将对象的值拷贝过来;
    • 如对象中有管理资源,会导致多个对象共用一份资源,销毁释放时就会造成重复释放的问题;

深拷贝

  • 会给每个对象独立分配资源,保证多个对象间不会因共享资源而造成多次释放;
    • 如一个类中涉及到资源管理,其拷贝构造、赋值运算符重载、及析构函数都必须显式给出,一般按深拷贝方式提供;
//传统保守写法
//拷贝构造
string(const string& s)
	:_str(new char[strlen(s._str) + 1])
{
	strcpy(_str, s._str);
}

//赋值运算符重载
string& operator=(const string& s)
{
	if (this != &s)
	{
		char* tmp = new char[strlen(s._str) + 1];
		strcpy(tmp, s._str);
		delete[]_str;
		_str = tmp;
	}
	return *this;
}

//析构函数,因为新开了空间
~string()
{
    if(_str)
    {
        delete[] _str;
		_str = nullptr;
    }
}
//现代写法
//拷贝构造
string(const string& s)
	:_str(nullptr)
{
    //利用默认构造函数,申请新空间,然后交换
	string strtmp(s._str); 
	swap(_str, strtmp._str);
}

//赋值运算符重载
string& operator=(string s)
{
    //直接传值传参调用拷贝构造,然后交换
	swap(_str, s._str);
    return *this;
}

//赋值运算符重载
//string& operator=(const string& s)
//{
//	if (this != &s)
//	{
//		string strtmp(s._str);
//		swap(_str, strtmp._str);
//	}
//	return *this;
//}

注:数组越界读一般检测不出来,越界写是抽查可能会检测出来;string都会被检测出来;

写时拷贝(了解)

  • 即延时拷贝,在浅拷贝的基础上增加了引用计数的方式来实现;某个对象写入时,在深拷贝对象;
  • 引用计数是用来记录资源使用者的个数,构造时计数加1,每增加一个对象使用该资源计数就在加1,当某个对象销毁时,计数就减1,如计数为1,说明该对象是资源的最后使用者,将资源释放;

注:vs是深拷贝,不是写时拷贝,g++是写时拷贝;

四,string类的模拟实现

namespace mystring
{
	class string
	{
	public:
		//迭代器iterator
		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; }
    
    private:
		char* _str;
		size_t _size;
		size_t _capacity; //不包含'\0'

	public:
		//默认构造
		string(const char* str = "") //也可为"\0"
		{
			_size = strlen(str);
			_capacity = _size;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		//拷贝构造
		string(const string& s)
			:_str(nullptr)
			,_size(0)
			,_capacity(0)
		{
			string tmp(s._str);
			swap(tmp);
		 }

		//赋值运算符重载
		string& operator=(string s)
		{
			swap(s);
			return *this;
		}

		//析构函数
		~string()
		{
			delete[]_str;
			_str = nullptr;
		}

    //************************************************
		//Capacity
		void reserve(size_t newcapacity)
		{
			if (_capacity < newcapacity)
			{
				char* str = new char[newcapacity + 1];
				strcpy(str, _str);
				delete[] _str;
				_str = str;
				_capacity = newcapacity;
			}
		}

		void resize(size_t newsize, char c = '\0')
		{
			if (newsize > _capacity)
				reserve(newsize);
			for (size_t i = _size; i < newsize; i++)
				_str[i] = c;
			_size = newsize;
			_str[_size] = '\0';	
		}

		//访问
		char& operator[](size_t index)
		{
			assert(index < _size);
			return _str[index];
		}
		const char& operator[](size_t index) const
		{
			assert(index < _size);
			return _str[index];
		}
		const char* c_str()const
		{
			return _str;
		}

		//修改
		void push_back(char c)
		{
			//if (_size == _capacity)
			//{
			//	size_t newcapacity = _capacity ? _capacity * 2 : 4;
			//	reserve(newcapacity);
			//}
			//_str[_size++] = c;
			//_str[_size] = '\0';

			insert(_size, c);
		}
		void append(const char* str)
		{
			//size_t len = strlen(str);
			//if (_size + len > _capacity)
			//{
			//	reserve(_size + len);
			//}
			//strcpy(_str + _size, str);
			//_size += len;
			insert(_size, str);
		}
		string& operator+=(char c)
		{
			push_back(c);
			return *this;
		}
		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}
		string& operator+=(const string& s)
		{
			*this += s._str; //append(s._str);
			return *this;
		}

		string& insert(size_t pos, char c)
		{
			assert(pos <= _size);
			if (_size == _capacity)
			{
				size_t newcapacity = _capacity ? _capacity * 2 : 4;
				reserve(newcapacity);
			}

			size_t end = _size + 1;
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				--end;
			}
			_str[end] = c;
			++_size;
			_str[_size] = '\0';

			return *this;	
		}
		string& insert(size_t pos, const char* str)
		{
			assert(pos <= _size);
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}

			size_t end = _size + 1;
			while (end > pos)
			{
				_str[end + len - 1] = _str[end - 1];
				--end;
			}
			for (int i = 0; i < len; i++)
			{
				_str[pos + i] = str[i];
			}
			_size += len;

			return *this;
		}

		string& erase(size_t pos, size_t len = npos)
		{
			assert(pos < _size);
			if (len == npos || len >= _size - pos)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}
			return *this;
		}

		//查找
		size_t find(char c, size_t pos = 0) const
		{
			for (size_t i = pos; i < _size; i++)
			{
				if (_str[i] == c)
					return i;
			}
			return npos;
		}
		//kmp方法,bm方法
		size_t find(char* substr, size_t pos = 0) const
		{
			const char* p = strstr(_str + pos, substr);
			if (p == nullptr)
				return npos;
			else
				return  p - _str;
		}

		void clear()
		{
			_size = 0;
		}

		//交换
		void swap(string& s) 
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}

		size_t size()const
		{
			return _size;
		}
		size_t capacity()const
		{
			return _capacity;
		}

		const static size_t npos;
	};

//**********************************************

	const size_t string::npos = -1;

	//非成员函数重载
	//+尽量少用
	string operator+(const string& s, const char c)
	{
		string tmp = s;
		tmp += c;
		return tmp;
	}
	string operator+(const string& s, const char* str)
	{
		string tmp = s;
		tmp += str;
		return tmp;
	}
	string operator+(const string& s1, const string& s2)
	{
		string tmp = s1;
		tmp += s2;
		return tmp;
	}

	std::istream& operator>>(std::istream& in, string& s)
	{
		//in >> ch; //获取不到' '或'\0'
		s.clear();
		char c = in.get();
		while (c != ' ' && c != '\n')
		{
			s += c;
			c = in.get();
		}
		return in;
	}
	std::ostream& operator<<(std::ostream& out, const string& s)
	{
		for (size_t i = 0; i < s.size(); i++)
		{
			out << s[i];
		}
		return out;
	}
	std::istream& getline(std::istream& in, string& s)
	{
		s.clear();
		char c = in.get();
		while (c != '\n')
		{
			s += c;
			c = in.get();
		}
		return in;
	}

	bool operator>(const string& s1, const string s2)
	{
		size_t i1 = 0, i2 = 0;
		while (i1 < s1.size() && i2 < s2.size())
		{
			if (s1[i1] > s2[i2])
				return true;
			else if (s1[i1] < s2[i2])
				return false;
			else
			{
				++i1;
				++i2;
			}
		}
		if (i1 == s1.size())
			return false;
		else
			return true;
	}
	bool operator==(const string& s1, const string s2)
	{
		size_t i1 = 0, i2 = 0;
		while (i1 < s1.size() && i2 < s2.size())
		{
			if (s1[i1] != s2[i2])
				return false;
			else
			{
				++i1;
				++i2;
			}
		}
		if (i1 == s1.size() && i2 == s2.size())
			return true;
		else
			return false;
	}
	inline bool operator!=(const string& s1, const string s2)
	{
		return !(s1 == s2);
	}
	inline bool operator>=(const string& s1, const string s2)
	{
		return (s1 > s2 || s1 == s2);
	}
	inline bool operator<(const string& s1, const string s2)
	{
		return !(s1 >= s2);
	}
	inline bool operator<=(const string& s1, const string s2)
	{
		return !(s1 > s2);
	}
}

C++初阶—string类 C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。 阅读详情

相关推荐

【C++初阶】一篇手撕string类

了解,学会string类的基本操作用法,进入STL学习

2201_75642960的博客 1235

C++ string 基本用法

C++string函数的基本使用方法

可涵的博客 3万+

科研党福音:如何用Zotero+Paper Agent打造你的AI论文速递系统(附详细配置教程)

本文为科研工作者提供了一套利用Zotero和开源工具Paper Agent构建自动化AI论文速递系统的详细教程。该系统能基于用户在Zotero中的文献库智能学习研究兴趣,每日自动从arXiv等平台筛选、下载并深度解读最相关的前沿论文,生成个性化日报,实现从被动接收到主动精准获取的知识工作流重塑。

kite3的博客 514

C++——string 类

在构造时,将资源的计数给成1,每增加一个对象使用该资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该对象时资源的最后一个使用者,将该资源释放;3)用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。4)auto不能作为函数的参数,可以做返回值,但是建议谨慎使用。

2301_80636070的博客 3047

不止于ACC:用CarSim的‘Multiple Objects’和路径跟踪器玩转复杂交通流场景

本文深入探讨了如何利用CarSim的'Multiple Objects'模块和路径跟踪器模拟复杂交通流场景,超越传统ACC测试的局限。通过批量控制、动态交互和参数化设计,实现多车智能响应和复杂轨迹模拟,适用于连续变道、拥堵博弈、匝道汇流等真实交通场景。

weixin_30954265的博客 497

Rocky Linux 9.2:利用LVM动态调整/home与/根分区空间分配

本文详细介绍了在Rocky Linux 9.2系统中,如何利用LVM(逻辑卷管理器)动态调整/home与根分区(/)的空间分配。针对根分区空间不足而/home分区闲置的常见问题,文章提供了从检查磁盘布局、备份数据、卸载分区、调整逻辑卷大小到重建文件系统的完整操作步骤,并重点说明了XFS与EXT4文件系统在缩容时的不同处理方法,帮助系统管理员安全、在线地实现存储空间的灵活调配。

weixin_29271263的博客 177

C++之string

我等必将复起,古木已发新枝。

iwkxi的博客 3400

物理信息神经网络(PINNs)在交通运输领域的应用

物理信息神经网络(PINNs)在交通运输领域的应用研究结合了数据驱动与物理模型约束,通过嵌入交通流守恒定律等物理信息,显著提升了交通状态估计与预测的精度。该技术仅需少量观测数据(流量、速度、密度等),即可实现高精度建模,尤其适用于数据稀疏场景。研究重点包括:交通状态估计与预测、参数辨识、交通控制优化等领域,同时面临计算成本高、物理模型依赖性等挑战。未来需解决大规模异构数据处理问题,以进一步推动智能交通系统发展。

qq_49609070的博客 944

C++——string类

  文章目录构造数据方法字符串存取赋值字符串搜索比较方法和函数字符串修改方法输出与输入       ISO/ANSI C++98 标准通过添加 string 类扩展了 C++ 库,因此现在可以 string 类型的变量(使用 C++ 的话说是对象)而不是字符数组来存储字符串。string 类使用起来比数组简单,同时提供了将字符串作为一种数据类型的表示方法。   要使用 string 类,必须在程序中包含头文件 string。   在很多方面,使用 string 对象的方式与使用

qwjy的博客 3404

Zigbee通信(CC2530终端 + ESP32-C6协调器)

实现了CC2530 zigbee终端与ESP32-C6 zigbee协调器的通信交互。

Ecsply的博客 2564

VM与欧姆龙PLC通讯设置实战:Fins TCP/UDP协议详解

本文详细解析了VM(VisionMaster)与欧姆龙PLC通过Fins TCP/UDP协议进行通讯的实战设置。内容涵盖网络配置、协议选择(TCP可靠性与UDP实时性)、VM端地址映射与数据点添加、以及数据接收解析流程,并提供了常见错误排查与高级调试技巧,帮助视觉与自动化工程师快速实现稳定可靠的工业通讯集成。

weixin_29172963的博客 328

C++初阶:初识STL、String类接口详细讲解(万字解析)

1.STL介绍1.1概念(标准模板库) 1.2版本问题(主流有4个) 1.3 STL六大组件 2.string类的基本介绍 3.string类对象的构造 4.访问及遍历操作 4.1operator[] ([]加下标) 4.2基于范围for 4.3使用迭代器(最推荐使用) 5.string的迭代器 (lterator) 5.1介绍 5.2 begin () 和end () (正向和常正向) 5.3rbegin () 和rend () (反向和常反向) 6.string类对象的容量操作 6.1sizeleng

qq_74415153的博客 1807

同花顺客户端数据采集:Hook注入与内存解密实战

在金融量化领域,客户端数据采集是获取低延迟、高精度行情的关键技术路径。其底层涉及进程通信、内存加密、反调试等典型Windows逆向工程问题。理解API Hook原理与AES-CBC动态密钥派生机制,有助于突破传统HTTP爬虫在国产金融软件中的失效困境。该技术不依赖网络劫持,而聚焦于本地进程内函数拦截与运行时内存解析,具备离线、可控、合规等工程优势,广泛应用于Level2行情、逐笔委托、分笔成交等高频数据场景,是量化基础设施中‘端侧数据主权’的重要实现方式。

weixin_30496999的博客 855

【C++初阶】--- string类

std::string 类是 C++ 标准库中用于处理和操作字符串的一个类,它定义在 头文件中。相较于 C 语言里以空字符 ‘\0’ 结尾的字符数组(C 风格字符串),std::string 类提供了更便捷、安全且强大的字符串处理功能。

Wangshijie1015的博客 761

基于 ESP32 的宿舍洗浴热水余量预测与智能排队提醒系统设计与实现

本系统以 ESP32 为主控核心,通过超声波液位传感器实时监测储热水箱剩余水量,配合 DS18B20 温度传感器采集水温数据,建立热水余量预测模型估算可用洗浴时长;同时通过红外人体传感器统计浴室排队人数,结合人均洗浴时长计算预计等待时间,并通过 OLED 屏本地显示 + WiFi Web 服务器远程推送的方式实现排队提醒功能。

weixin_42300449的博客 45

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++初阶-string类的简单应用

这个题目其实我想在讲getline函数时就讲了,这个就是getline函数和rfind函数(我自己差点也忘记这个函数了)的应用了!//a.size()-1是真实长度//而再减去剩余的长度即真实长度//因为rfind是返回找到的元素的下标(若为字符串则返回最前的一个元素下标)这讲的题目比较经典,所以提前讲了,之后在把string类手动实现后我将讲解一些扩展的string题目,下节将讲解:string类的手动实现。喜欢的可以一键三连哦,下讲再见!

博客是在C++/Java/Liunx/算法的学习阶段所写的博客,内容可能不是很全面 1057

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【C++初阶】string类

【C++初阶】string类

2301_78022459的博客 1175

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

c++初阶知识——string类详解

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

qq_58761784的博客 2873

《C++初阶之STL》【string类:详解 + 实现】

本文系统介绍了C++中string类的核心知识点。首先对比了C语言字符串与C++ string类的差异,然后详细解析了标准库string类的三大组成部分:成员函数、非成员函数重载和成员常量。特别分析了MSVC和g++编译器下string类的底层实现差异,包括MSVC的联合体优化设计(小字符串优化)和g++的指针实现方式。

序属秋秋秋的博客 2450

C++初阶-string类1

kw=string之后我们将围绕这个文档进行一系列string类的讲解。这篇博客讲了string的一些基本知识和一些成员函数的用法,但是由于string的成员函数比较多,所以需要下讲继续讲了,喜欢的可以一键三连哦!

博客是在C++/Java/Liunx/算法的学习阶段所写的博客,内容可能不是很全面 1139

C++初阶——string类

string类是,它提供对字符串的管理和操作功能。:string类是一个动态数组,可以存储字符序列,并且可以自动调整大小以适应存储的字符数量。:string类提供了多种构造函数,允许从C风格字符串、另一个string对象、字符数组等创建字符串对象。:string类支持赋值运算符=,用于将一个字符串的内容复制给另一个字符串对象。:string类提供了.size()、.length()、.empty()、等方法来获取字符串的大小和容量。

qq_55890817的博客 1418

【C++初阶】学习string类的模拟实现

前面已经学习了string类的用法,这篇文章将更深入的学习string类,了解string类的底层是怎么实现的。当然,这里只是模拟一些常用的,不常用的可以看文档学习。

2301_77459845的博客 2764

C++初阶之string类

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

qq_51604748的博客 956

C++初阶 String类详解

本篇博客介绍了String类的基本使用方法以及使用String类刷一些题目

小萌新的博客 1611

C++初阶:string类

string类详解,string底层实现

weixin_63143943的博客 1664

C++初阶 String类

auto关键字的使用,范围for的使用, string类对象的常见构造 , string类对象的容量操作, string类对象的访问及遍历操作 ,string类对象的修改操作, string类非成员函数

2501_94364163的博客 735
上一篇: C++初阶 —— STL简介
下一篇: C++初阶 —— vector类
挨代码
博客等级 码龄5年 1696粉丝 384原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值