标签:
STL 源码剖析 string
最近打算好好看看STL源码实现...
各种定义找不到头都大了.
首先你需要一个帮手,ctags不行我们就用global(什么东西自己搞定,这么不介绍了).
在STL库的路径下 bits/stringfwd.h你能找到一下定义
你会发现我们常用的标准库类string实质上是basic_string
class string的定义有2000+行,我们这里不会给出所有细节,仅就个人觉得重要和感兴趣的地方进行分析.
你看,这里类的设计者把对于和string类的各种相关变量类型都做了声明,value_type, size_type ...
class _Rep用来表示字符串
string类总是用_M_length + 1个字符并且确保最后一个为‘\0‘空字符结尾来表示字符串.
而申请内存的时候总是会多申请一些(_M_capacity),_M_capacity 大于等于 _M_length.
上图是struct _Rep_base的定义,我们可以看到这里使用的是struct 而不是class,之前已经处于private标号中,所以整个结构体都是私有的.
注意到struct _Rep是 _Rep_base的派生类.
之后我们还能看到这里提供了string类的容量接口capacity()
这里STL的作者写了两个功能同样的接口,可能是为了便于程序员调用.size()与length()同一个意义,都返回当前字符串的长度,但是不包括空字符,这种风格和C的strlen()保持了一致.
我们写个小demo测试一下
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str("hello world");
cout << "capacity" << str.capacity() << endl;
cout << "size " << str.size() << endl;
cout << "length " << str.length() << endl;
cout << "max_size" << str.max_size() << endl;
return 0;
}
你会看到各种构造函数的实现:
/**
* @brief Construct an empty string using allocator @a a.
*/
explicit
basic_string(const _Alloc& __a);
/**
* @brief Construct string with copy of value of @a str.
* @param __str Source string.
*/
basic_string(const basic_string& __str);
/**
* @brief Construct string as copy of a substring.
* @param __str Source string.
* @param __pos Index of first character to copy from.
* @param __n Number of characters to copy (default remainder).
*/
basic_string(const basic_string& __str, size_type __pos,
size_type __n = npos);
/**
* @brief Construct string as copy of a substring.
* @param __str Source string.
* @param __pos Index of first character to copy from.
* @param __n Number of characters to copy.
* @param __a Allocator to use.
*/
basic_string(const basic_string& __str, size_type __pos,
size_type __n, const _Alloc& __a);
/**
* @brief Construct string initialized by a character %array.
* @param __s Source character %array.
* @param __n Number of characters to copy.
* @param __a Allocator to use (default is default allocator).
*
* NB: @a __s must have at least @a __n characters, '\\0'
* has no special meaning.
*/
basic_string(const _CharT* __s, size_type __n,
const _Alloc& __a = _Alloc());
/**
* @brief Construct string as copy of a C string.
* @param __s Source C string.
* @param __a Allocator to use (default is default allocator).
*/
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
/**
* @brief Construct string as multiple characters.
* @param __n Number of characters.
* @param __c Character to use.
* @param __a Allocator to use (default is default allocator).
*/值得一提的是最后我们常用的字符串类初始化方式是给它一个C类型的字符串,作为初始化的参数.而这里其实就是调用的这里
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());上面还给出了其他用字符串类引用做初始化参数的构造函数.
我们还看到了clear(), empty接口
clear()用于擦出字符串,使之为空.而empty()怎用于检测字符串是否为空.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str("hello");
cout << "capacity" << str.capacity() << endl;
cout << "size " << str.size() << endl;
cout << "length " << str.length() << endl;
cout << "max_size" << str.max_size() << endl;
if (str.empty() == true)
{
cout << "empty" << endl;
}
else
{
cout << "Not empty" << endl;
}
str.clear();
if (str.empty() == true)
{
cout << "empty" << endl;
}
else
{
cout << "Not empty" << endl;
}
return 0;
}
未完待更新~
标签:
原文地址:http://blog.csdn.net/cinmyheart/article/details/44714393