如何使用c++ 17的std:: string_view避免字符串拷贝

  介绍

如何使用c++ 17的std:: string_view避免字符串拷贝?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

c++中std:: string是日常编码中经常使用的一个类,使用起来非常方便,但是也存在一些弊端。

如下代码,参数传递的过程发生了内存分配(内存分配)和内存拷贝。

空白乐趣(const std:: string&s) {
  std:: cout & lt; & lt;年代& lt; & lt;std:: endl;
  }
  
  const char * ch=澳愫脀orld";//坏,昂贵的如果弦长
  有趣(ch);

再看下面的常用的字符串截取实现:

//很长的字符串
  std:: string str=發llloooonnnngggg sssstttrrriiinnnggg";//坏,昂贵的如果弦长
  std:: cout & lt; & lt;str.substr(15日10)& lt; & lt;& # 39;\ n # 39;; 

为了进一步的压榨程序的性能,需要移除掉这些昂贵的字符串内存分配和拷贝操作c + + 17中提供了std:: string_view可以帮助我们实现这一功能,该类并不持有字符串的拷贝,而是与源字符串共享其内存空间。

<强> string_view构造函数

 constexpr basic_string_view () noexcept;(因为c++ 17)
  constexpr basic_string_view (const basic_string_view&其他)noexcept=违约;(因为c++ 17)
  constexpr basic_string_view (const图* s, size_type计数);(因为c++ 17)
  constexpr basic_string_view (const图*);(因为c++ 17)
  template<类,类End> 

虽然没有定义参数为std:: string的std:: string_view函数、下面的代码仍然可以通过编译。

 std:: string str(“你好字符串视图!“);
  std:: string_view sview (str); 

因为std:: string类重载了std:: string到std:: string_view的转换操作符。

 

有了std:: string_view,函数参数不管是字符串数组指针,还是std:: string,都不需要拷贝内存源字符串。

//很长的字符串
  std:: string str=發llloooonnnngggg sssstttrrriiinnnggg";//挥写唇ǜ北镜暮梅椒?
  std::=str string_view视图;//string_view: substr返回一个新的string_view
  std:: cout & lt; & lt;视图。substr (10) & lt; & lt;& # 39;\ n # 39;; 

同理,字符串的substr()函数也不需要再进行拷贝了,这对于非常长的字符串,可以有效的提升程序的性能表现。

<强> std:: string_view注意事项

由于std:: string_view并不持有字符串的内存,所以它的生命周期一定要比源字符串的生命周期长。一些典型的生命周期管理错误的例子:

 std:: string_view sv=std:: string(“你好world");
  
  std:: string_view有趣(){
  std:: string str(“你好world");
  返回std:: string_view (str);
  }

std:: string_view的结尾并没有\ 0结束符,所以在输出std:: string_view的时候要注意边界,如下代码:

 # include & lt; iostream>
  # include & lt; vector>
  # include & lt; string>
  # include & lt; string_view>
  
  int main () {
  const char * ch=澳愫脀orld";
  
  std:: string_view sv (ch 2);
  
  std:: cout & lt; & lt;sv & lt; & lt;std:: endl;
  
  std:: cout & lt; & lt;sv.data () & lt; & lt;std:: endl;
  
  返回0;
  }

程序输出:

  hello world

std:: cout & lt; & lt;sv.data () & lt; & lt;std:: endl;这行代码输出了hello world,这是因为sv仍然指向源字符串内存,调用sv.data()打印时,仍然沿用了c++对于字符串的约定,直到遇到结束符\ 0时,打印才结束,这时候就输出了完整的源字符串内容。当然这里明显是不符合预期的,尤其是std:: string_view指向的字符串没有\ 0结束符的时候,程序很容易出现潜在的内存问题,所以此处一定要小心。

看完上述内容,你们掌握如何使用c++ 17的std:: string_view避免字符串拷贝的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

如何使用c++ 17的std:: string_view避免字符串拷贝