string的erase用法

Update:2020-3-2。

之前总结的,初学编程,较为青涩,有很多表达不是很清楚,表述不完善,有幸得到一个博友的指正,于是再次更新。

但由于水平有限,如果发现有问题和需要补充的,请务必留言评论。

文章分为两部分:

第一部分为简单的方法使用探究,目的是为了快速入门学回使用。

第二部分为简单的源码分析,目的是为了简单的了解一下运行的方式。

目录

Update:2020-3-2。

1.阅读前提:

2.使用环境:

3.方法探究:

3.1删除一段字符串

3.1.1测试一:

3.1.2测试二:

3.1.3结论:

3.2删除一个字符串

3.2.1测试一:

3.2.2测试二:

3.2.3结论:

4.方法分析

4.1整体结构的把握:

4.2方法深入的探究:

4.2.1_M_mutate()方法探索。

4.2.2_M_Rep探究

4.2.3对元素的修改

5.参考博客:


 

1.阅读前提:

  1. 知道迭代器(iterator)是什么。
  2. string中返回值为迭代器的方法:
iterator begin();
interator end();
iterator erase(iterator _position);
iterator erase(iterator _first,iterator _last);
interator insert(iterator __p,_CharT __c);
const_iterator begin();
const_iterator cbegin();
const_iterator  cend();
const_iterator end();
const_reverse_iterator crbegin();
const_reverse_iterator crend();

可以看到,string内置的迭代器的返回值只有begin(),end()。

  • begin()返回string中第一个元素所对应的位置。
  • end()返回string中最后一个元素的后一个位置(可以用字符串末尾的"\0"来理解:我们不写"\0",但还是存在。
    注意,这里是可以理解,真正的解释可能不是这个...)。
  • 可以看出来了,这个英文解释很清楚:指向最后一个元素之后的元素。

erase是我们这次探究的。insert是不用考虑的,所以,很多操作都是基于begin()和end()来实现的。

const的不考虑。

2.使用环境:

编译器:Dev-C++ 5.11的所有默认设置。

3.方法探究:

首先获得一个string对象,然后看其erase都有重载。

感觉这前两个个就比较常用了,现在探究一下这两个。(第三个返回一个basic_string类,感觉应该是构造的时候使用的)

3.1删除一段字符串

看参数应该差不多理解了:删除一段的字符串。

iterator erase(iterator _first,iterator _last)

参数:传入删除首尾的迭代器,返回一个迭代器。

3.1.1测试一:

由图可得:删除了[23456],即[第2位,倒数第3位)。返回了7,即删除字符串的后一位

3.1.2测试二:

删除了[2],即[第2位,第3位)。返回了3.

3.1.3结论:

iterator erase(iterator _first,iterator _last)

方法删除区间为前闭后开区间。返回删除字符串的后一位。

3.2删除一个字符串

看参数应该就清楚了,删除指定位置的字符。

iterator erase(iterator _position)

参数:传入指定位置的迭代器。

3.2.1测试一:

删除了第二个字符,即第二位,返回3,即删除元素的后一位。

3.2.2测试二:

删除了最后倒数第二位,返回结果为9。

3.2.3结论:

删除指定位置的字符,返回删除位置的后一位。

4.方法分析

4.1整体结构的把握:

首先点开erase的方法,进入了basic_string.h文件。可以看到里面简单的介绍:

进入basic_string.tcc文件,可以看到其中的源码:基本一样。

到了这里,应该就清楚参数和返回值了。

4.2方法深入的探究:

可以看出erase方法的核心就是其中的_M_mutate()和_M_rep()了。下面我们来尝试探索一下。

4.2.1_M_mutate()方法探索。

也就是说_M_mutate()就是获得对应空间的方法。

4.2.2_M_Rep探究

这个是一个结构体,basic_string.h中的[147,170]行里面。

作用大概也是内存计数和状态。

代码在下面:其中的Alloc就在Rep结构体的下面。有兴趣的自行了解吧。

     struct _Rep_base
      {
	size_type		_M_length;
	size_type		_M_capacity;
	_Atomic_word		_M_refcount;
      };

      struct _Rep : _Rep_base
      {
	// Types:
	typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;

	// (Public) Data members:

	// The maximum number of individual char_type elements of an
	// individual string is determined by _S_max_size. This is the
	// value that will be returned by max_size().  (Whereas npos
	// is the maximum number of bytes the allocator can allocate.)
	// If one was to divvy up the theoretical largest size string,
	// with a terminating character and m _CharT elements, it'd
	// look like this:
	// npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
	// Solving for m:
	// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
	// In addition, this implementation quarters this amount.
	static const size_type	_S_max_size;
	static const _CharT	_S_terminal;

	// The following storage is init'd to 0 by the linker, resulting
        // (carefully) in an empty string with one reference.
        static size_type _S_empty_rep_storage[];

        static _Rep&
        _S_empty_rep() _GLIBCXX_NOEXCEPT
        { 
	  // NB: Mild hack to avoid strict-aliasing warnings.  Note that
	  // _S_empty_rep_storage is never modified and the punning should
	  // be reasonably safe in this case.
	  void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
	  return *reinterpret_cast<_Rep*>(__p);
	}

        bool
	_M_is_leaked() const _GLIBCXX_NOEXCEPT
        { return this->_M_refcount < 0; }

        bool
	_M_is_shared() const _GLIBCXX_NOEXCEPT
        { return this->_M_refcount > 0; }

        void
	_M_set_leaked() _GLIBCXX_NOEXCEPT
        { this->_M_refcount = -1; }

        void
	_M_set_sharable() _GLIBCXX_NOEXCEPT
        { this->_M_refcount = 0; }

	void
	_M_set_length_and_sharable(size_type __n) _GLIBCXX_NOEXCEPT
	{
#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
	  if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
	    {
	      this->_M_set_sharable();  // One reference.
	      this->_M_length = __n;
	      traits_type::assign(this->_M_refdata()[__n], _S_terminal);
	      // grrr. (per 21.3.4)
	      // You cannot leave those LWG people alone for a second.
	    }
	}

	_CharT*
	_M_refdata() throw()
	{ return reinterpret_cast<_CharT*>(this + 1); }

	_CharT*
	_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
	{
	  return (!_M_is_leaked() && __alloc1 == __alloc2)
	          ? _M_refcopy() : _M_clone(__alloc1);
	}

	// Create & Destroy
	static _Rep*
	_S_create(size_type, size_type, const _Alloc&);

	void
	_M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT
	{
#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
	  if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
	    {
	      // Be race-detector-friendly.  For more info see bits/c++config.
	      _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount);
	      if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
							 -1) <= 0)
		{
		  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount);
		  _M_destroy(__a);
		}
	    }
	}  // XXX MT

	void
	_M_destroy(const _Alloc&) throw();

	_CharT*
	_M_refcopy() throw()
	{
#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
	  if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
            __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
	  return _M_refdata();
	}  // XXX MT

	_CharT*
	_M_clone(const _Alloc&, size_type __res = 0);
      };

4.2.3对元素的修改

basic_string.h中从1428行开始就是修改了,一直到1734行,由于有点多,而且自己就能找到,所以就不再贴到这里了,有兴趣的自行查看。里面就有各种修改操作。这里就不局限于erase了。包括insert,pop等操作。

5.参考博客:

https://blog.csdn.net/liuyuan185442111/article/details/45870441?locationnum=3&fps=1

更加具体的解读参考csdn博主专栏STL中string中源码解读:https://blog.csdn.net/abortexit/category_296884.html

 

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值