1 string简介
string类型支持长度可变的字符串,C++标准库将负责管理与存储字符串相关的内存,以及提供各种有用的操作。
2 string头文件
#include<string>
#using std:string;
3 string 操作
3.1 string初始化
sting s1; //默认构造函数
string s2(s1); //将s2初始化为s1的副本
string s3("value"); //将s3初始化为字符串“value”的副本
string s4(n,'c'); //将s4初始化为字符'c'的n个副本
3.2 获取string对象中字符的个数——string::size()
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("Hello World!");
cout<<"count:"<<s1.size()<<endl;
}
输出:
[root@localhost tmp]# ./string
count:12
这里需要注意的是,
string::size()操作返回的类型是string::size_type,不是int类型,也绝对不允许将返回值赋值给int类型。
3.3 判断string对象是否为空——string::empty()
返回bool类型
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("Hello World!");
string s2;
cout<<"s1 is empty?:"<<(s1.empty()?"True":"False")<<endl;
cout<<"s2 is empty?:"<<(s2.empty()?"True":"False")<<endl;
}
输出:
[root@localhost tmp]# ./string
s1 is empty?:False
s2 is empty?:True
3.4 string的关系操作符(==,!=,<,<=,>,>=)
1) 两个string对象相等是指他们的长度相同,且含有排序相同的字符。
2) 如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于长的string对象
3) 如果两个string对象的字符不同,则比较第一个不匹配的字符。
3.5 string 对象赋值
赋值操作之后,s4包含了s2字符串的一个副本
#include<iostream>
#include<string>
using namespace std;
int main()
{
cout << s3 << endl;
cout << s4 << endl;
}
输出:
Hello World!
Hello World!
[root@localhost tmp]#
3.6 string对象的连接及与字符串字面值的连接
字符串字面值不能单独用+操作进行连接操作
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s3 = "Hello World!";
string s4 = "My God!";
string s5 = s3+s4;
string s6 = s3 + "My God!";
//string s7 = "Hello World!" + "My God!"; error
cout << s5 << endl;
cout << s6 << endl;
}
输出:
Hello World!My God!
Hello World!My God!
[root@localhost tmp]#
string.cpp:15:31: error: invalid operands of types ‘const char [13]’ and ‘const char [8]’ to binary ‘operator+’
string s7 = "Hello World!" + "My God!";
3.7 string下标操作([])
string类型通过下标操作符([])来访问string对象中的单个字符。下标操作符需要取一个string::size_type类型的值,来标明要访问字符的位置。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s3 = "Hello World!";
for(string::size_type i=0;i!=s3.size();i++)
{
cout<<s3[i]<<endl;
}
s3[0]='*'; //操作左值
cout << s3 << endl;
}
输出
H
e
l
l
o
W
o
r
l
d
!
*ello World!
[root@localhost tmp]#
4 string的实现
4.1 string的实现
其实string是basic_string模板类的一种实现.在stl_string_fwd.h文件中可以看得出:
#ifndef __SGI_STL_STRING_FWD_H
#define __SGI_STL_STRING_FWD_H
#include <stddef.h>
#include <stl_config.h>
#include <stl_alloc.h>
#include <char_traits.h>
__STL_BEGIN_NAMESPACE
template <class _CharT,
class _Traits = char_traits<_CharT>,
class _Alloc = __STL_DEFAULT_ALLOCATOR(_CharT) >
class basic_string;
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
static const char* __get_c_string(const string&);
__STL_END_NAMESPACE
#endif /* __SGI_STL_STRING_FWD_H */
// Local Variables:
// mode:C++
4.2 string的底层存储实现(非__STL_USE_STD_ALLOCATORS)
basic_string继承了_String_base
template <class _CharT, class _Traits, class _Alloc>
class basic_string : private _String_base<_CharT,_Alloc> {
public:
typedef _CharT value_type;
typedef _Traits traits_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
看下_String_base类
template <class _Tp, class _Alloc> class _String_base {
public:
typedef _Alloc allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
protected:
typedef simple_alloc<_Tp, _Alloc> _Alloc_type;
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
// Precondition: 0 < __n <= max_size().
_Tp* _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n) {
if (__p)
_Alloc_type::deallocate(__p, __n);
}
void _M_allocate_block(size_t __n) {
if (__n <= max_size()) {
_M_start = _M_allocate(__n);
_M_finish = _M_start;
_M_end_of_storage = _M_start + __n;
}
else
_M_throw_length_error();
}
void _M_deallocate_block()
{ _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; }
_String_base(const allocator_type&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
_String_base(const allocator_type&, size_t __n)
: _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ _M_allocate_block(__n); }
~_String_base() { _M_deallocate_block(); }
void _M_throw_length_error() const;
void _M_throw_out_of_range() const;
};
留意到_String_base的非空构造函数调用_M_allocate_block分配内存空间,本质上是调用STl的内存分配器实现的:
_Tp* _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }
所以本质上,string是一片STL管理的堆内存(STL内存池或直接malloc分配的)