STL 源码剖析 # class string #

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;
}

未完待更新~

时间: 2024-10-04 12:09:41

STL 源码剖析 # class string #的相关文章

《STL源码剖析》---stl_iterator.h阅读笔记

STL设计的中心思想是将容器(container)和算法(algorithm)分开,迭代器是容器(container)和算法(algorithm)之间的桥梁. 迭代器可以如下定义:提供一种方法,能够依序寻访某个容器内的所有元素,而又无需暴露该容器的内部表达方式. 在阅读代码之前,要先了解一个新概念:Traits编程技法 template <class T> struct MyIter { typedef T value_type //内嵌型别声明 T *ptr; MyIter(T *p = 0

STL&quot;源码&quot;剖析-重点知识总结

STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合套用: 容器(Containers):各种数据结构,如:vector.list.deque.set.map.用来存放数据.从实现的角度来看,STL容器是一种class template. 算法(algorithms):各种常用算法,如:sort.search.copy.erase.从实现的角度来看,STL算法

《STL源码剖析》---stl_hashtable.h阅读笔记

在前面介绍的RB-tree红黑树中,可以看出红黑树的插入.查找.删除的平均时间复杂度为O(nlogn).但这是基于一个假设:输入数据具有随机性.而哈希表/散列表hash table在插入.删除.查找上具有"平均常数时间复杂度"O(1):且不依赖输入数据的随机性. hash table的实现有线性探测.二次探测.二次散列等实现,SGI的STL是采用开链法(separate chaining)来实现的.大概原理就是在hash table的每一项都是个指针(指向一个链表),叫做bucket.

《STL源码剖析》---stl_alloc.h阅读笔记

这一节是讲空间的配置与释放,但不涉及对象的构造和析构,只是讲解对象构造前空前的申请以及对象析构后空间怎么释放. SGI版本的STL对空间的的申请和释放做了如下考虑: 1.向堆申请空间 2.考虑了多线程.但是这节目的只是讲解空间配置与释放,因此忽略了多线程,集中学习空间的申请和释放. 3.内存不足时的应变措施 4.考虑到了内存碎片的问题.多次申请释放小块内存可能会造成内存碎片. 在C++中,内存的申请和释放是通过operator new函数和operator delete函数,这两个函数相当于C语

c++ stl源码剖析学习笔记(一)

template <class InputIterator, class ForwardIterator>inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,ForwardIterator result) 函数使用示例 #include <algorithm> #include <iostream> #include <memory> #inclu

【转载】STL&quot;源码&quot;剖析-重点知识总结

原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合套用: 容器(Containers):各种数据结构,如:vector.list.deque.set.map.用来存放数据.从实现的角度来看,STL容器是一种class template. 算法(algorithms):各种常用算法,如:sort.se

STL源码剖析——基本算法stl_algobase.h

前言 在STL中,算法是经常被使用的,算法在整个STL中起到非常重要的作用.本节介绍的是一些基本算法,包含equal,fill,fill_n,iter_swap,lexicographical_compare,max,min,mismatch,swap,copy,copy_backward,copy_n.其中一个比较重要的算法就是copy,针对copy的剖析在源码中可以看到详细的注解.本文剖析的源码出自SGL STL中的<stl_algobase.h>文件. 基本算法剖析 #ifndef __

《STL源码剖析》---stl_algobase.h阅读笔记

STL标准中没有区分基本算法或复杂算法,单SGI把常用的一些算法定义在<stl_algobase.h>只中,其他算法定义在<stl_algo.h>中. stl_algobase.h中的算法,比较值得学习的是copy(),它"无所不用其极"的改善效率.copy的目的是复制一段元素到指定区间,复制操作最容易想到赋值操作符=,但是有的赋值操作符=是trivial的,可以直接拷贝.关于赋值操作符=是不是trivial的,可以参考"Memberwise copy

《STL源码剖析》---stl_pair.h阅读笔记

pair是STL中的模板类型,它可以存储两个元素,它也被称作"对组".在map中已经用到了它,pair其实就是一个struct结构,存有两个public的元素,重载了几个运算符,没有什么成员函数,源代码很简单. G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_pair.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy,