c++ string类_C++|细说STL string类概貌及底层细节

C语言中的字符串称为C风格字符串,是一个以'0'结尾的字符数组,string.h库只提供了有限、不甚安全的字符串操作函数。char str[]只能定义编译期确定大小的字符串,而保存在堆内存的动态字符数组却需要考虑释放内存的问题,且想要实现自变长的弹性大小也存在诸多纷繁的操作细节。C++ STL中的string类一揽子解决了诸如此类的问题。除此以外,STL算法通过traits和iterator中间层来操作各类容器,也包括string。

C++中常用的string类其实是一个typedef:

typedef basic_string string;

basic_string是STL中的类模板,用char实例化这个类模板,取别名为string。

之所以在String中定义basic_string模板类,而不是直接的string模板类,是因为其考虑处理的容器元素,不单只是一个字节的ASCII字符,还有宽字符wchar_t以及char16_t、char32_t或unsigned char等。

1 封装字符串的由来

1.1 不封装的缺陷

char *cp = "abc";    // 其实是const,字面量"abc"并不存储在栈区,而是常量区//cp[2] = 'D';           // errorchar arr[4] = "abc"; // 固定大小int size = 4;char *dp = new char[size];dp[0]='a';dp[1]='b';dp[2]='c';dp[3]='0';cout<

1.2 封装为类:可变长、并自动释放堆内存

封装一个字符指针,由这个指针指向一块new出来的堆内存,并按传入的字符串字面量复制入这块堆内存。

cbfa21779b6470a8eb0edad785f2ded4.png
// string.h#ifndef __MYSTRING__#define __MYSTRING__class String{public:                                    String(const char* cstr=0);                        String(const String& str);                       String& operator=(const String& str);            ~String();                                       char* get_c_str() const { return m_data; }private:   char* m_data;};#include inlineString::String(const char* cstr){   if (cstr) {      m_data = new char[strlen(cstr)+1];      strcpy(m_data, cstr);   }   else {         m_data = new char[1];      *m_data = '0';   }}inlineString::~String(){   delete[] m_data;}inlineString& String::operator=(const String& str){   if (this == &str)      return *this;   delete[] m_data;   m_data = new char[ strlen(str.m_data) + 1 ];   strcpy(m_data, str.m_data);   return *this;}inlineString::String(const String& str){   m_data = new char[ strlen(str.m_data) + 1 ];   strcpy(m_data, str.m_data);}// String_test.cpp#include using namespace std;ostream& operator<using namespace std;int main(){  String s1("hello");   String s2("world");      String s3(s2);  cout << s3 << endl;    s3 = s1;  cout << s3 << endl;       cout << s2 << endl;    cout << s1 << endl;       String *p = new String[3];  p[0] = "We";  p[1] = "are";  p[2] = "one";  char* str = p[2].get_c_str();  cout << str << endl;  delete[] p;  cin.get();}/*worldhelloworldhelloone*/

进一步,可以封装为类模板,可以访问不同的字符类型。

2 STL

STL string模板类在上述基础上实现了类型泛化,并封装了很多的成员函数,且有STL算法库中的函数模板支持。

2.1 两个类模板

basic_string Generic string class (class template )

char_traits Character traits (class template )

2.2 模板类4个

string String class (class )

u16string String of 16-bit characters (class )

u32string String of 32-bit characters (class )

wstring Wide string (class )

2.3 转换函数或函数模板

stoi Convert string to integer (function template )

stol Convert string to long int (function template )

stoul Convert string to unsigned integer (function template )

stoll Convert string to long long (function template )

stoull Convert string to unsigned long long (function template )

stof Convert string to float (function template )

stod Convert string to double (function template )

stold Convert string to long double (function template )

to_string Convert numerical value to string (function )

to_wstring Convert numerical value to wide string (function )

3 basic_string模板类

basic_string模板类声明:

template < class charT,           class traits = char_traits,    // basic_string::traits_type           class Alloc = allocator        // basic_string::allocator_type           > class basic_string; 

basci_string封装一根指向字符类型的指针,也就是管理一个以'0'结尾的字符动态数组,有了诸多操作的封装,中间层有迭代器iterator和萃取器traits,traits用于迭代器、型别等的提取,iterator用于封装一个basci_string容器类对象指针,一些独立于容器的算法可以通过迭代器来操作容器元素。

char_traits用于类模板容器元素的型别选择,也是一个模板类:

template  struct char_traits;template <> struct char_traits;template <> struct char_traits;template <> struct char_traits;template <> struct char_traits;

该特性类别规定了“复制字符”或“比较字符“的做法,如果不指定该特性类别,会根据现有的字符型别采用默认的特性类别。

其成员函数包括:

eqCompare characters for equality ( public static member function )ltCompare characters for inequality ( public static member function )lengthGet length of null-terminated string ( public static member function )assignAssign character ( public static member function )compareCompare sequences of characters ( public static member function )findFind first occurrence of character ( public static member function )moveMove character sequence ( public static member function )copyCopy character sequence ( public static member function )eofEnd-of-File character ( public static member function )not_eofNot End-of-File character ( public static member function )to_char_typeTo char type ( public static member function )to_int_typeTo int type ( public static member function )eq_int_typeCompare int_type values ( public static member function )

实例:

// char_traits::compare#include    // std::cout#include      // std::basic_string, std::char_traits#include      // std::tolower#include     // std::size_t// case-insensitive traits:struct custom_traits: std::char_traits {    static bool eq (char c, char d)     {         return std::tolower(c)==std::tolower(d);     }    static bool lt (char c, char d)     {         return std::tolower(c)<:tolower static int compare char p const q std::size_t n while if return lt main std::basic_string> foo,bar;    foo = "Test";    bar = "test";    if (foo==bar)         std::cout << "foo and bar are equal";    return 0;}// output: // char_traits::compare

allocator有默认值,定义字符串类别所采用的内存模式,将容器与物理存储细节分隔,提供了一套分配与释放堆内存的标准方式,其型别为charT,可以是char、wchar_t、char16_t、char32_t。

类模板实例化的模板类:

stringString class (class )wstringWide string (class )u16string String of 16-bit characters (class )u32string String of 32-bit characters (class )

所用字符串类型均使用相同接口,用法和问题都一样,以下是部分成员函数:

(constructor)Construct basic_string object (public member function )(destructor)String destructor (public member function )operator=String assignment (public member function )sizeReturn size (public member function )lengthReturn length of string (public member function )operator[]Get character of string (public member function )atGet character of string (public member function )operator+=Append to string (public member function )appendAppend to string (public member function )push_backAppend character to string (public member function )insertInsert into string (public member function )replaceReplace portion of string (public member function )c_strGet C-string equivalentfindFind first occurrence in string (public member function )rfindFind last occurrence in string (public member function )substrGenerate substring (public member function )compareCompare strings (public member function )operator+Concatenate strings (function template )operator>>Extract string from stream (function template )getlineGet line from stream into string (function template )

4 string类

string类是使用char(即字节)作为其字符类型的basic_string类模板的一个实例化,其有默认char_traits和分配器类型。

其迭代器为a random access iterator to char。

string提供的接口类似于标准字节容器的接口,但添加了专门设计用于使用单字节字符字符串操作的功能。

string类独立于使用的编码处理字节,如果用于处理多字节或可变长度字符(如UTF-8)的序列,则该类的所有成员(如长度或大小)及其迭代器仍将按字节(而不是实际的编码字符)操作。string类的型别虽是char,但因为char是一个字节,其有天然的按字节(byte)处理的优势,也是汉字等一些其它编码的字符能被string类处理的原因,处理完后再按其原本的编码解析即可。

wstring类是使用wchar_t(即字节)作为其字符类型的basic_string类模板的一个实例化。

在Windows下,wchar_t占2个字节(byte);在Linux下,wchar_t占4个字节。

u16string、u32string则是确定长度的宽字节类型。

wstring、u16string、u32string类有与string类相同接口的成员函数。

-End-

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python可以调用Gpu吗_python可以开发app吗

python可以开发app吗&#xff1f;python是可以开发app的&#xff0c;例如我们可以使用kivy开发安卓APP&#xff0c;Kivy是一套专门用于跨平台快速应用开发的开源框架&#xff0c;使用Python和Cython编写&#xff0c;对于多点触控有着非常良好的支持&#xff0c;不仅能让开发者快…

kubectl查看node状态_适用于初学者的基本 kubectl 和 Helm 命令 | Linux 中国

去杂货店“采购”这些命令&#xff0c;你需要用这些 Kubernetes 工具来入门。-- Jessica Cherry去杂货店“采购”这些命令&#xff0c;你需要用这些 Kubernetes 工具来入门。最近&#xff0c;我丈夫告诉我他即将要去参加一个工作面试&#xff0c;面试时他需要在计算机上运行一些…

pycharm pyqt5 pyrrc_编程基础 | Pycharm安装、配置、快捷键

Pycharm可以去官网下载Pycharm的安装激活jar包的目的就是让截获截止时间并骗过pycharm;将jar包放入pycharm在你本地的安装目录bin下。并且修改两个以 vmoptions为结尾的启动文件如图所示:并且在两个文件后追加 -javaagent:D:devAppPyCharm 2017.3.2inJetbrainsCrack-2.6.10-rel…

php的web表单系统源码毕设_从业十多年看了千百套Java毕设项目,整理出100个精品!免费分享...

加班无数个昼夜看了千百套Java毕设项目&#xff0c;发现这100个精品&#xff01;今天免费分享给大家&#xff01;再给大家推荐一条由浅入深的JAVA学习路径&#xff0c;首先完成 Java基础、JDK、JDBC、正则表达式等基础实验&#xff0c;然后进阶到 J2SE 和 SSH 框架学习。最后再…

xbox360无线手柄接收器驱动_八位堂USB 无线接收器让手柄不闲置,无线畅玩各平台游戏...

遥想儿时每逢周末放假&#xff0c;得闲便会打上一下午的游戏。富有活跃想象力的游戏画面和不断操作游戏手柄发出的愉悦打击声&#xff0c;总会令人感到如此如醉。长大了&#xff0c;随着科技创新进步与物质生活的丰富&#xff0c;我们都会向往童年时游戏带来的满足愉快之情&…

在scrapy中parse函数里面xpath的内容打印不出来_如何正确的使用Scrapy ?

本节是 《Python爬虫从入门到进阶》课程中的一节&#xff0c;课程购买链接(PC访问需要微信扫码) &#xff0c;目前已更新80% 课程购买课程请扫码&#xff1a;Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架。只需要编写很少的代码就能实现抓取功能&a…

绳索受力分析的软件_【硕士论文】供热管网管道支架载荷分析与优化设计

摘 要改革开放后我国经济快速发展&#xff0c;随着集中供热事业的扩大&#xff0c;集中供暖越来越受到广大民众的欢迎&#xff0c;居民冬季用热为主的集中供暖面积在连年递增&#xff0c;已经成为主要一种供暖方式。集中供热作为城市公共服务功能中重要的一项工作&#xff0c;对…

python-docx 如何获取当前字号_餐饮老字号迈上“云端”

原标题&#xff1a;餐饮老字号迈上“云端”老字号陈麻婆豆腐旗舰店。 杨予頔 摄中新网成都10月31日电 (单鹏)临近中午&#xff0c;成都餐饮老字号“钟水饺”文殊院店的前台站满身穿黄色和蓝色服装的“外卖小哥”&#xff0c;拿到打包好的钟水饺后&#xff0c;他们急匆匆地转身…

进入hbase命令_Zookeeper、Hbase安装部署

zookeeper安装与配置使用xftp将压缩包传入/soft中创建zookeeper数据存放目录mkdir /soft/zookeeperchmod 766 /soft/zookeeper分别在三台服务上面依次执行 echo id > /var/zookeeper/myid 命令创建zookeeper编号的myid文件echo 1 > /soft/zookeeper/myidecho 2 > /sof…

c++new时赋初值_C高级编程精髓之内存管理,万千码农踩过的雷,大神带你走出雷区...

今天给大家分享C高级编程精华片之内存管理——欢迎跟大家一起踏进内存这片雷区&#xff0c;然后带大家从雷区中走出来&#xff01;程序员们经常编写内存管理程序&#xff0c;往往提心吊胆。如果不想触雷&#xff0c;唯一的解决办法就是发现所有潜伏的地雷并且排除它们&#xff…

为什么用pyqt的不多_现在农村提倡用天然气和清洁煤球取暖,为何农民不爱用?看完懂了...

近几年华北很多农村响应保护环境的政策&#xff0c;大多数农村家庭都安装了天然气。冬季的取暖方式也从以前的烧煤取暖改成了烧天然气或清洁煤球取暖。对于安装天然气并烧天然气或清洁煤球取暖&#xff0c;大多数农民都很抗拒&#xff0c;为什么农村人不愿意烧天然气和清洁煤球…

两种参数类型_布尔参数这些缺点不能忍?不如试试枚举吧

全文共2222字&#xff0c;预计学习时长9分钟图源&#xff1a;unsplash在代码库中使用布尔标志值来管理状态机似乎听起来是个不错的办法&#xff0c;但事实并非如此。布尔值恐怕是很多程序员接触到的第一种数据类型&#xff0c;它非常简单&#xff0c;只有两种状态: true 和fals…

405 not allowed怎么解决_英语口语:“您拨叫的用户不在服务区”这类电话常用语怎么说...

1、空号&#xff1a;中文&#xff1a;您好&#xff01;您所拨打的号码是空号&#xff0c;请核对后再拨。英文&#xff1a;Sorry! The number you dialed does not exist, please check it and dial later.2、被叫用户关机&#xff1a;中文&#xff1a;您好&#xff01;您所拨打…

利用代码分别实现jdk动态代理和cglib动态代理_代理模式实现方式及优缺点对比...

作者&#xff1a;爱宝贝丶来源&#xff1a;https://my.oschina.net/zhangxufeng/blog/1633187代理模式最典型的应用就是AOP&#xff0c;本文结合主要讲解了代理模式的几种实现方式&#xff1a;静态代理和动态代理&#xff0c;这里动态代理又可以分为jdk代理和Cglib代理&#xf…

防抖 节流_防抖节流与前端性能优化

在我们日常的开发中经常会用到一些容易被反复触发的事件。比如&#xff1a;scroll、resize、鼠标事件(mousemove,mouseover等)、键盘事件(keyup、keydown)。频繁触发回调导致的大量计算会引发页面的抖动甚至卡顿。为了规避这种情况&#xff0c;我们需要一些手段来控制事件被触发…

惠普10代的服务器有哪些型号,英特尔官方科普:秒懂十代酷睿型号怎么认!

今日&#xff0c;英特尔官方微博再次放出科普&#xff1a;十代酷睿处理器是如何命名的&#xff1f;英特尔介绍&#xff0c;以酷睿i7-1065G7为例&#xff0c;“i7”为产品型号&#xff0c;“1065”中的“10”代表十代酷睿&#xff0c;“65”为CPU代号&#xff0c;“G7”为显卡性…

form提交后台注解拿不到数据_浏览器是如何将用户数据发送到服务器的?

今天是刘小爱学习Java的第89天。感谢你的观看&#xff0c;谢谢你。话不多说&#xff0c;开始今天的学习&#xff1a;在学习之前&#xff0c;先思考如下问题&#xff1a;对于浏览器来说&#xff1a;如何将用户数据发送到服务器呢&#xff1f;数据传输的格式是怎么样的呢&#xf…

proxmoxve打造云桌面_微软云电脑Cloud PC曝光:配置一般还不便宜

光纤宽带的普及和提速、5G的兴起&#xff0c;让云电脑、云游戏、云手机等产品和应用红火起来。而微软也正在开发一款名为Cloud PC的云端Windows操作系统&#xff0c;并计划2021年正式推出。据报道&#xff0c;Cloud PC是由Azure云服务支撑&#xff0c;基于虚拟桌面打造的&#…

alpine linux图形界面_跟光磊学Linux运维-Linux入门与基本使用

认识Linux用户在安装CentOS8.2时&#xff0c;设置过root用户的密码&#xff0c;同时也创建了用户guanglei。其中root用户是系统自带的管理员账户&#xff0c;也被称为超级用户&#xff0c;root用户接近系统完整的控制能力&#xff0c;对系统损害几乎有无限的能力。运维人员在生…

休眠 嵌入式_内幕消息:嵌入式软件挤出最低功耗模式

低功耗运行仍然是各行业应用的关键驱动因素。随着睡眠模式的增加&#xff0c;电源管理突然从单纯的硬件问题转移到软件开发人员必须考虑的事情上。功耗模式的最简单应用是当系统空闲时&#xff0c;将其置于休眠状态。然而&#xff0c;今天的MCU提供多种低功耗模式&#xff0c;进…