1. 简介

该StringPiece是PCRE的实现,是对字符串的一个proxy类而已(即设计模式中的代理模式)。

2. 背景

很多时候,当传入一个字符串到函数时,往往只是读取字符串时

若使用std::string,当实参为const char *时,会分配内存并拷贝该字符串以生成一个std::string

当一个函数接受一个const std::string,而在该函数内部,又需要传递该值到另一个函数,则又需要重新生成一个std::string

3. 目的

当某个接口参数是接受字符串类型时,为了减少不必要的开销

该类型可以接受const char *,std::string,减少冗余代码编写

4. 要点

① 成员变量

 const char*   ptr_;int           length_;

通过保存字符串指针和长度,来避免不必要的复制;
开销很低,只需要sizeof(const char*) + sizeof(int)字节;
内部的ptr_ 这块内存不归他所有,要确保在StringPiece生命期内,该数据可用

② 构造函数

StringPiece(): ptr_(NULL), length_(0) { }
StringPiece(const char* str): ptr_(str), length_(static_cast<int>(strlen(ptr_))) { }
StringPiece(const unsigned char* str): ptr_(reinterpret_cast<const char*>(str)),length_(static_cast<int>(strlen(ptr_))) { }
StringPiece(const string& str): ptr_(str.data()), length_(static_cast<int>(str.size())) { }
StringPiece(const char* offset, int len): ptr_(offset), length_(len) { }

参数都是字符串且都是const类型,只用于提取,而不用于修改

③ 字符串比较

bool operator==(const StringPiece& x) const
{return ((length_ == x.length_) &&(memcmp(ptr_, x.ptr_, length_) == 0));
}
bool operator!=(const StringPiece& x) const
{return !(*this == x);
}#define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp)                             \bool operator cmp (const StringPiece& x) const {                           \int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_)));          \}STRINGPIECE_BINARY_PREDICATE(<,  <);STRINGPIECE_BINARY_PREDICATE(<=, <);STRINGPIECE_BINARY_PREDICATE(>=, >);STRINGPIECE_BINARY_PREDICATE(>,  >);
#undef STRINGPIECE_BINARY_PREDICATE

以<为例,宏展开后代码如下

bool operator < (const StringPiece& x) const {                           \int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \return ((r < 0) || ((r == 0) && (length_ < x.length_)));          \}

比较”abcd” < “abcdefg”, 返回的结果为true
比较”abcdx” < “abcdefg”, 返回结果为false

④ 操作

const char* data() const
{return ptr_;
}
int size() const
{return length_;
}
bool empty() const
{return length_ == 0;
}
const char* begin() const
{return ptr_;
}
const char* end() const
{return ptr_ + length_;
}void clear()
{ptr_ = NULL;length_ = 0;
}
void set(const char* buffer, int len)
{ptr_ = buffer;length_ = len;
}
void set(const char* str)
{ptr_ = str;length_ = static_cast<int>(strlen(str));
}
void set(const void* buffer, int len)
{ptr_ = reinterpret_cast<const char*>(buffer);length_ = len;
}char operator[](int i) const
{return ptr_[i];
}void remove_prefix(int n)
{ptr_ += n;length_ -= n;
}void remove_suffix(int n)
{length_ -= n;
}
int compare(const StringPiece& x) const
{int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_);if (r == 0) {if (length_ < x.length_) r = -1;else if (length_ > x.length_) r = +1;}return r;
}string as_string() const
{return string(data(), size());
}void CopyToString(string* target) const
{target->assign(ptr_, length_);
}// Does "this" start with "x"
bool starts_with(const StringPiece& x) const
{return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0));
}

⑤ Traits
由于StringPiece只持有目标指针,所以是POD类型,并且拥有平凡构造函数,所以可以定义如下的type traits以指示STL采用更为高效的算法实现。

#ifdef HAVE_TYPE_TRAITS
// This makes vector<StringPiece> really fast for some STL implementations
template<> struct __type_traits<StringPiece> {typedef __true_type    has_trivial_default_constructor;typedef __true_type    has_trivial_copy_constructor;typedef __true_type    has_trivial_assignment_operator;typedef __true_type    has_trivial_destructor;typedef __true_type    is_POD_type;
};
#endif

⑥ 输出

// allow StringPiece to be logged
std::ostream& operator<<(std::ostream& o, const StringPiece& piece);

重载<<方便打印和日志输出

5. 源码

Github

6. 参考

http://qianchenglong.github.io/2016/05/28/C++-StringPiece/
https://blog.csdn.net/q5707802/article/details/78420629
POD类型参考https://zhuanlan.zhihu.com/p/45545035

muduo StringPiece详解相关推荐

  1. muduo scoped_ptr详解

    1. 简介 scoped_ptr类似于智能指针只能在作用域里使用,不希望被转让. 2. 类与接口 #ifndef _SCOPE_PTR_HH #define _SCOPE_PTR_HH // scop ...

  2. muduo BlockingQueue详解

    1. 简介 利用条件变量和std::deque实现阻塞队列 2. 类与接口 插入数据,有2个版本 void put(const T& x) 非常量可以初始化一个底层const,反过来却不行 可 ...

  3. muduo Date详解

    1. 简介 用于Julian Day和普通年月日的转换 2. 类与接口 2.1 class Date : public copyable ① Date::Date(int y, int m, int ...

  4. muduo Timestamp详解

    1. 简介 Timestamp用于提供时间戳相关的工具函数. 2. 类与接口 ① string toString() const 返回时间的字符串形式,例如1649224501.687051 ② st ...

  5. muduo Thread详解

    1. 简介 Thread用于线程管理. 2. pthread_atfork 在进行linux系统里开发时,经常会调用linux的系统函数fork来产生一个子进程,如果父子进程都没有用到pthread线 ...

  6. muduo Mutex详解

    1. 简介 多线程环境下利用pthread进行共享资源的互斥操作,该模块使用了Thread safety annotations技术,若使用了cling c++解析器,可以在编译时进行线程安全分析,如 ...

  7. muduo Logging详解

    1. 简介 Logging用于将日志事件信息(时间 日志级别 文件名 行号等)加到输出缓冲区,默认输出到stdout. 2. 类与接口 ① 私有内部类Impl 将日志事件(时间 日志级别 文件名 行号 ...

  8. Kati详解-Android10.0编译系统(五)

    摘要:本节主要来讲解Kati把Makefile编译成build-xxx.ninja,那么Kati是什么? 是如何工作的呢? 阅读本文大约需要花费24分钟. 文章首发微信公众号:IngresGe 专注于 ...

  9. sstream类的详解

     sstream类的详解             sstream类详细介绍 C++引入了ostringstream.istringstream.stringstream这三个类,要使用他们创建对象 ...

最新文章

  1. mysql rollback函数_PHP mysqli_rollback() 函数_程序员人生
  2. C51位运算应用技巧
  3. 特征值 与特征向量(机器学习算法原理与实践)
  4. modelsim加入xilinx ISE库的方法
  5. Sharepoint 2010 应用范围
  6. 错误:子进程 已安装 pre-removal 脚本 返回了错误号 1
  7. Android快速批量打渠道包(AndroidManifestModifier)
  8. POJ3348 Cows
  9. keil c51注册机2032
  10. macbook视频格式转换_如何将Mac视频格式转换
  11. ★★★5230打字慢的解决方法...绝对有用...只需要在手机上轻微的设置一下(转)...
  12. java怎么求偏态函数_树的不同形态
  13. Android+刷固件,(57M2)海信ip906h强刷系统安卓固件包及刷机教材
  14. 关于‘\0’ ,‘0’, “0” ,0的理解
  15. 音视频系列1:流媒体
  16. Scratch之顺序、循环、选择三种程序结构
  17. MFC+opencv实现摄像头的打开与关闭
  18. Linux下软连接的概念
  19. 为什么要用MQ,MQ是什么?(消息队列)
  20. K8S 生态周报| Helm v3.4 发布

热门文章

  1. 221027|多元正态分布假设检验
  2. plt.tight_layout()
  3. SpringSecurity的配置
  4. selectedIndex 用法
  5. S32K的pwm_pal组件使用
  6. Jenkins 详细介绍
  7. JS判断Email格式(可验证英文和中文邮箱)
  8. python爬虫基础之AJAX页面的抓取
  9. 猿创征文|程序员的浪漫(代码猜诗词)
  10. vlad用python实现_「vlad」VLAD算法简介 - seo实验室