muduo StringPiece详解
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详解相关推荐
- muduo scoped_ptr详解
1. 简介 scoped_ptr类似于智能指针只能在作用域里使用,不希望被转让. 2. 类与接口 #ifndef _SCOPE_PTR_HH #define _SCOPE_PTR_HH // scop ...
- muduo BlockingQueue详解
1. 简介 利用条件变量和std::deque实现阻塞队列 2. 类与接口 插入数据,有2个版本 void put(const T& x) 非常量可以初始化一个底层const,反过来却不行 可 ...
- muduo Date详解
1. 简介 用于Julian Day和普通年月日的转换 2. 类与接口 2.1 class Date : public copyable ① Date::Date(int y, int m, int ...
- muduo Timestamp详解
1. 简介 Timestamp用于提供时间戳相关的工具函数. 2. 类与接口 ① string toString() const 返回时间的字符串形式,例如1649224501.687051 ② st ...
- muduo Thread详解
1. 简介 Thread用于线程管理. 2. pthread_atfork 在进行linux系统里开发时,经常会调用linux的系统函数fork来产生一个子进程,如果父子进程都没有用到pthread线 ...
- muduo Mutex详解
1. 简介 多线程环境下利用pthread进行共享资源的互斥操作,该模块使用了Thread safety annotations技术,若使用了cling c++解析器,可以在编译时进行线程安全分析,如 ...
- muduo Logging详解
1. 简介 Logging用于将日志事件信息(时间 日志级别 文件名 行号等)加到输出缓冲区,默认输出到stdout. 2. 类与接口 ① 私有内部类Impl 将日志事件(时间 日志级别 文件名 行号 ...
- Kati详解-Android10.0编译系统(五)
摘要:本节主要来讲解Kati把Makefile编译成build-xxx.ninja,那么Kati是什么? 是如何工作的呢? 阅读本文大约需要花费24分钟. 文章首发微信公众号:IngresGe 专注于 ...
- sstream类的详解
sstream类的详解 sstream类详细介绍 C++引入了ostringstream.istringstream.stringstream这三个类,要使用他们创建对象 ...
最新文章
- mysql rollback函数_PHP mysqli_rollback() 函数_程序员人生
- C51位运算应用技巧
- 特征值 与特征向量(机器学习算法原理与实践)
- modelsim加入xilinx ISE库的方法
- Sharepoint 2010 应用范围
- 错误:子进程 已安装 pre-removal 脚本 返回了错误号 1
- Android快速批量打渠道包(AndroidManifestModifier)
- POJ3348 Cows
- keil c51注册机2032
- macbook视频格式转换_如何将Mac视频格式转换
- ★★★5230打字慢的解决方法...绝对有用...只需要在手机上轻微的设置一下(转)...
- java怎么求偏态函数_树的不同形态
- Android+刷固件,(57M2)海信ip906h强刷系统安卓固件包及刷机教材
- 关于‘\0’ ,‘0’, “0” ,0的理解
- 音视频系列1:流媒体
- Scratch之顺序、循环、选择三种程序结构
- MFC+opencv实现摄像头的打开与关闭
- Linux下软连接的概念
- 为什么要用MQ,MQ是什么?(消息队列)
- K8S 生态周报| Helm v3.4 发布