个人备案网站建设方案书网络营销推广怎么做
news/
2025/9/29 17:44:28/
文章来源:
个人备案网站建设方案书,网络营销推广怎么做,网页设计师必须知道的网站,帝国cms调用网站名称string模拟实现 构造函数和析构函数begin和endreserve和resizepush_back和appendc_strempty#xff0c;size#xff0c;capacity#xff0c;clear拷贝构造和赋值和比较大小[]重载insert和erasefind查找 前面我们已经对string进行了简单的介绍#xff0c;只要会用各个函数即… string模拟实现 构造函数和析构函数begin和endreserve和resizepush_back和appendc_stremptysizecapacityclear拷贝构造和赋值和比较大小[]重载insert和erasefind查找 前面我们已经对string进行了简单的介绍只要会用各个函数即可下面是string的模拟实现。 在这里我们可以定义一个自己的命名空间防止与库里的string造成冲突。
namespace haifan
{class string{public:.....private:char* _str;size_t _size;size_t _capacity;};
}构造函数和析构函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JhE4Trrp-1690193767195)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230724170813742.png)]
这是库里的几种构造函数在这里我只实现了一种。
如果在传参的时候我们是以haifan::string a的形式或者是以 haifan::string b(123) 我们可以考虑用 string(const char* str ) 这样的形式来写构造函数当没有参数的时候就用str的缺省值有参数就用传递的参数。
string(const char* str )
{_size strlen(str);_capacity _size;_str new char[_capacity 1];memcpy(_str, str, _size 1);
}析构函数很简单把_str释放掉在置为空指针即可
~string()
{delete[] _str;_str nullptr;_capacity _size 0;
}begin和end
begin和end分别由两种写法一种是带const的一种是不带的。
typedef char* iterator;
typedef const char* const_iterator;const_iterator begin() const
{return _str;
}const_iterator end() const
{return _str _size;
}iterator begin()
{return _str;
}iterator end()
{return _str _size;
}reserve和resize
reserve是为字符串预留空间的一个函数并且只有一个参数表示要为字符串预留多少空间如果n要比capacity小可以不做处理反之要为字符串预留n 1的空间因为要放一个\0
void reserve(size_t n)
{if (_capacity n){//注意还有一个\0char* tmp new char[n 1];memcpy(tmp, _str, _size 1);delete[] _str;_str tmp;_capacity n;}
}resize是用字符c来填充多出的元素空间。在改变元素个数时如果是增多可能会改变底层容量的大小如果减少底层空间总大小不变。
void resize(size_t n, char c \0)
{if (_capacity n){_str[n] \0;_size n;}else{reserve(n);for (int i _size; i n; i){_str[i] c;}_str[n] \0;_size n;}
}push_back和append
push_back是在字符串的尾部添加一个字符—尾插但在进行插入的时候要注意空间是否足够对此进行一个检查即可。 在插入字符后别忘了在将\0进行一次尾插 void push_back(char ch)
{if (_size 1 _capacity){if (_capacity 0){reserve(4);}elsereserve(2 * _capacity);}_str[_size] ch;_str[_size] \0;
}append是将一个字符串进行尾插同样要先进行空间检查。如果空间不足将空间开辟到跟尾插后的字符串一样的大小即可。
void append(const char* str)
{size_t len strlen(str);if (len _size _capacity){reserve(len _size);}memcpy(_str _size, str, len 1);_size len;}c_str
c_str是将string类以C字符串的形式返回。
const char* c_str() const
{return _str;
}emptysizecapacityclear
empty用于判断string是否为空。
bool empty() const
{return _capacity 0;
}size用于判断string的长度
size_t size() const
{return _size;
}capacity用于判断string当前的容量
size_t capacity() const
{return _capacity;
}clear用于清空string但是capacity并不会被清0
void clear()
{_size 0;_str[_size] \0;
}拷贝构造和赋值
拷贝构造设计到了空间的开辟要用深拷贝浅拷贝可能会造成两个string共用同一块地址。
string(const string str)
{_str new char[str._capacity 1];_size str._size;_capacity str._capacity; memcpy(_str, str._str, str._capacity 1);
}赋值在这里只实现了两种情况一种是 string a b 另一种是 string a abcd前者利用拷贝构造先创建一个临时变量然后用swap将*this和tmp进行交换从而实现的目的。后者是开辟了一块空间将str里的内容拷贝到tmp里面然后将_strtmp。 void swap(string str){std::swap(_str, str._str);std::swap(_size, str._size);std::swap(_capacity, str._capacity);}string operator(const string s){if (this ! s){string tmp(s);swap(tmp);return *this;}}string operator (const char* str){char* tmp new char[strlen(str) 1];memcpy(tmp, str, strlen(str) 1);_size strlen(str);_capacity strlen(str) 1;delete[] _str;_str tmp;return *this;}和比较大小
加等于一个字符其实就是尾插 string operator (char c){push_back(c);return *this;}加等于一个字符串其实就是append string operator (const char* str){append(str);return *this;}用于比较的代码很好写只要写出来一个其他的都可以复用。
比如小于
两种情况 两个string的长度相同或者不相同如果相同直接memcpy进行字符串的比较即可如果不相同看哪个string短先比短的部分如果短的部分都相同则string长的大如果短的部分不相同在比较的时候做出判断即可。 bool operator(const string s){if (s._size _size){return memcpy(_str, s._str, _size);}else{if (_size s._size){for (int i 0; i s._size; i){if (_str[i] s._str[i]){return false;}}return false;}else{for (int i 0; i _size; i){if (_str[i] s._str[i]){return false;}}return true;}}//int ret memcmp(_str, s._str, _size s._size ? _size : s._size);//return ret 0 ? _size s._size : ret 0;}一个好理解的写法一个两行的写法写出来一个其他的都可以以为基础来写 bool operator(const string s){if (*this s || *this s){return true;}return false;}bool operator(const string s){return !(*this s);}bool operator(const string s){return !(*this s);}bool operator(const string s){return memcpy(_str, s._str, _size) 0 _size s._size;}bool operator!(const string s){return !(*this s);}[]重载
string类可以像字符串一样用下表来访问这是因为把[]进行了重载 char operator[] (size_t pos) {assert(pos _size);return _str[pos];}const char operator[] (size_t pos) const{assert(pos _size);return _str[pos];}insert和erase
在第pos位置上插入一个字符只需要把pos和pos后面的数据向后移动一位即可。 void insert(size_t pos,char c){assert(pos _size);if (_size 1 _capacity){reserve(2 * _capacity);}size_t tail _size;size_t head pos;while (tail pos tail ! npos){_str[tail] _str[tail - 1];tail--;}_str[pos - 1] c;_size;_str[_size] \0;} 在pos位置上插入一个字符串将pos和pos之后的数据向后移动字符串的长度即可。 void insert(size_t pos, const char* str){assert(pos _size);const size_t len strlen(str);if (len _size _capacity){reserve(len _size);}size_t tail _size;while (tail pos tail ! npos){_str[tail len] _str[tail];tail--;}for (int i 0; i len; i){_str[i pos] str[i];}_size len;_str[_size] \0;}erase(size_t pos 0, size_t len npos)
pos是要删除的起始位置len是要删除多少个不写默认把pos之后的元素全部删除。 npos是 size_t npos -1因为size_t是无符号数-1是一个正数且是一个及其大的值 void erase(size_t pos 0, size_t len npos){assert(pos _size);if (len pos _size){_str[pos] \0;_size pos;}else{size_t tail pos len;while (tail _size){_str[pos] _str[tail];}_size - len;_str[_size] \0;}}find查找
size_t find(char ch, size_t pos 0)
从pos位置开始查找某个字符如果找到了返回下标没找到返回npos size_t find(char ch, size_t pos 0){assert(pos _size);for (size_t i pos; i _size; i){if (_str[i] ch){return i;}}return npos;}size_t find(const char* str, size_t pos 0)
查找子串如果找到了返回第一次找到子串的位置反之返回npos size_t find(const char* str, size_t pos 0){assert(pos _size);const char* ptr strstr(_str pos, str);if (ptr){return ptr - _str;}else{return npos;}}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/922074.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!