菜鸟笔记
提升您的技术认知

c string封装-ag真人游戏

为什么要自己封装个string类?原因很多。qt库有自己的qstring类,mfc有自己的cstring类。stl标准库有自己的std::string类。mysql数据库的c api接口使用原生的char*指针。。。。。。

自己写的程序用那种string?没法选择。这时候可能需要写一个万能的string类和对接其它字符串类的接口。另一个原因是,效率问题;想获得最高的效率。还有就是本地化,国际化等原因。

从c 98开始,程序员们就开始造string轮子,方便自己学习和熟悉新的c 知识。现在我们用c 17的时髦思路,封装一个自己的string类。代码如下:

#include 
#include 
#include #include 
#include 
#include  //for std::strlen
#include 
class string{ private: enum{ object_size = sizeof(std::string) }; using string=std::string; using array=std::array ; std::variant data_; void set_data(const char* src) { if (src==nullptr){ data_.emplace(); auto& a = std::get(data_); a[0]=0; } else if (std::strlen(src)>=object_size){ data_.emplace(src); } else{ data_.emplace(); auto& a = std::get(data_); std::copy(src,src std::strlen(src),a.begin()); a[std::strlen(src)]=0; } } public: string(const char* src){ set_data(src); } void operator=(const char* src){ set_data(src); } const char* c_str(){ const char* ret = nullptr; switch (data_.index()){ case 1: ret = std::get(data_).c_str(); break; case 2: ret = std::get(data_).begin(); break; } return ret; } std::string_view str(){ switch (data_.index()){ case 0: return std::string_view(); case 1: return std::string_view(std::get(data_)); case 2: return std::string_view(std::get(data_).begin()); } } }; int main() { string s("12345"); std::cout << s.c_str() << std::endl; s = "..............................hello world!"; auto v1 = s.str(); auto v2 = v1.substr(v1.find_first_not_of('.')); std::cout << v2 << std::endl; }

现在分析一下,有哪些时髦(modern)的地方。

1)使用了variant,这个东西就是超级的union体。当字符串长度较小时,我们用std::array的不malloc()的喜感;当字符串长度较长时,我们用std::string的动态内存便利性。

2)string_view。这个是从boost::string_ref移植过来的好东西。

3)屏蔽了底层的技术细节。发明这个东西,不再需要什么placement new之类的胡言论语。

char buf_[64];
new (buf_) std::string("12345");  
reinterpret_cast(buf_)->~basic_string();  

4)剩下的功能,请尽情的改造吧

网站地图