SGI STL中string的源码解读(4)

4 篇文章 0 订阅

10.           reserve和resize函数

reserve函数:

reserve(size_type __res)

{

if (__res != this->capacity() || _M_rep()->_M_is_shared())

{

if (__res > this->max_size())

__throw_length_error(__N("basic_string::reserve"));

// Make sure we don't shrink below the current size

if (__res < this->size())

__res = this->size();

       //在这里不管如何都会新生成一份copy,其实我觉得也不一定的,特别是上面的if为真,并且没有对象共享的时候,不需要重新clone的。

const allocator_type __a = get_allocator();

_CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());

_M_rep()->_M_dispose(__a);

_M_data(__tmp);

}

}

resize函数:

resize(size_type __n, _CharT __c)

{

if (__n > max_size())

__throw_length_error(__N("basic_string::resize"));

const size_type __size = this->size();

if (__size < __n)

this->append(__n - __size, __c);

else if (__n < __size)

//当有string对象共享的时候,会重新分配空间,当没有对象共享的时候,实际上erase什么也没有做。

this->erase(__n);

}

11.           swap函数

swap(basic_string& __s)

{

//在这个函数中,开头的两个if判断很有意思,我猜测就是上述insertEraseoperator[]操作之后的string对象,因为swap之后,用户应该明白以前的迭代器都失效了,所以重新设置为单一对象标志。

if (_M_rep()->_M_is_leaked())

_M_rep()->_M_set_sharable();

if (__s._M_rep()->_M_is_leaked())

__s._M_rep()->_M_set_sharable();

//分配器相同的话直接交换指针

if (this->get_allocator() == __s.get_allocator())

{

_CharT* __tmp = _M_data();

_M_data(__s._M_data());

__s._M_data(__tmp);

}

else

{

    //否则不仅仅交换数据还要交换分配器的类型

const basic_string __tmp1(_M_ibegin(), _M_iend(),

__s.get_allocator());

const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),

this->get_allocator());

*this = __tmp2;

__s = __tmp1;

}

}

12.           append和operator+函数

append函数:

append(const basic_string& __str)

{

//在源代码中有一段注释,说明了为什么引入临时变量__size,主要是为了防止appending自身,修改了他自身的长度

const size_type __size = __str.size();

const size_type __len = __size + this->size();

if (__len > this->capacity())

this->reserve(__len);

return _M_replace_safe(this->size(), size_type(0), __str._M_data(), __str.size());

}

这个也比较简单,也调用了_M_repalce_safe函数。append函数共有三个重载形式,基本都是相同的代码。

Operator+函数:

operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,constbasic_string<_CharT, _Traits, _Alloc>& __rhs)

{

basic_string<_CharT, _Traits, _Alloc> __str(__lhs);

__str.append(__rhs);

return __str;

}

Operator共有5个重载函数,实现基本都类似于上面的函数直接调用append函数完成。

13.           其他函数

除了上述比较关键的函数意外,Basic_string模版类也提供其他的函数。

Ø         逻辑关系运算的函数,他们都是直接调用字符模板的函数完成的,如:<,>,==,!=等(有的函数还有多个重载形式);

Ø         纯算法型函数,find,find_of,find_first_of,find_first_not_of,find_last_of,find_last_not_of,rfind,rend等函数(有的函数还有多个重载形式)。提供这些函数的目的主要是为了效率和string种独特的操作(这些函数在很多书籍中都有很详细的使用介绍,其实现也不难);

Ø         STL容器必须支持的函数,如begin,end,empty等函数;

Ø         Operator<<,operator>>,getline函数这是使用GNU的扩展语法,其中他们的定义分别在istream.tcc和ostream.tcc中,在这里仅仅是引入模板类的声明;

Ø         最后还有就是string特有的函数,如c_str函数(返回字符串),length等函数。

 

14.     调试版本的string

在SGI STL中还提供了调试版本的string模版本,调试状态下的string主要继承于basic_string模板了以及_Safe_sequence模板类。前者就是我们上面所分析的代码,后者主要增加一些额外的调试信息。_Safe_sequence模板类继承于_Safe_sequence_base,主要保证经过操作之后迭代器是有效的。

15.     参考文献

主要是参考了SGI STL中的源文件Basic_string.h和Basic_string.tcc,其中这两个文件实现了basic_string模板类的所有函数。注意SGI STL中的*.tcc文件一般是对应于*.h中部分函数的实现和静态成员变量的定义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值