构造函数的实现
String(char *str = "")//在STL库中的string是不允许str是空指针所以在这里将它设为缺省函数就是给str默认值
:_size(strlen(str))//用初始化 列表时应注意在声明变量时的顺序
,_capacity(_size)
,_str(new char[_size+1]){
strcpy(_str, str);
}
拷贝构造函数
现代写法
String( const String& s){
:_str(nullptr){//在这里要注意一定要将_str初始化为空指针 不然之后交换指针当这个函数
String tmp(s._str); //运行完临时变量tmp调用析构函数会出现问题
swap(_str, tmp._str);
_size = s._size;
_capacity = s._capacity;
}
传统写法
String( const String& s)
:_str(new char[strlen(s._str)+1]){
strcpy(_str,s._str);
_size = s._size;
_capacity = s._capacity;
}
赋值运算符重载
现代写法
String& operator=(String s){//传进来的是值直接就进行了拷贝构造,拷贝的s就相当于临时变量
swap(_str, s._str);
_size = s._size;
_capacity = s._capacity;
return *this;
}
传统写法
String& operator=(const String& s){//返回值是引用可以进行连续赋值
if (this != &s){//传进来的是值直接就进行了拷贝构造,拷贝的s就相当于临时变量
delete[] _str;
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
_size = s._size;
_capacity = s._capacity;
}
return *this;//返回当前对象
}
扩容resever
void resever(size_t n){
if (n > _capacity){
char *tmp = new char[n+1];//创建临时变量进行扩容加一是因为字符串有\0
strcpy(tmp, _str);
delete[] _str;
_str = tmp;
_capacity = n;//更新容量
}
}
这几个函数都是面试经常问到的,迭代器就是用指针来实现的
代码里还实现了resize append 在任意位置增加字符和字符串,查找字符和字符串删除字符和字符串
代码
#include < iostream >
#include<assert.h>
using namespace std;
class String{
public:
typedef char* iterator;
typedef const char* const_iterator;
String(char *str = "")
:_size(strlen(str))
,_capacity(_size)
,_str(new char[_size+1]){
strcpy(_str, str);
}
String( const String& s)
:_str(nullptr){
String tmp(s._str);
swap(_str, tmp._str);
_size = s._size;
_capacity = s._capacity;
}
String& operator=(String s){
swap(_str, s._str);
_size = s._size;
_capacity = s._capacity;
return *this;
}
/*String& operator=(const String& s){
if (this != &s){
delete[] _str;
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
_size = s._size;
_capacity = s._capacity;
}
return *this;
}*/
~String(){
if (_str){
delete[] _str;
_str = nullptr;
}
}
void push_back(char c){
if (_size == _capacity){
if (_capacity == 0){
_str = new char[15];
}
else{
resever(_capacity*2);
}
}
_str[_size] = c;
_str[++_size] = '\0';
}
void resever(size_t n){
if (n > _capacity){
char *tmp = new char[n+1];
strcpy(tmp, _str);
delete[] _str;
_str = tmp;
_capacity = n;
}
}
iterator begin(){
return _str;
}
iterator end(){
return _str + _size;
}
const_iterator begin()const{
return _str;
}
const_iterator end()const{
return _str+_size;
}
void PrintfString(){
for (auto e : *this){
cout << e ;
}
}
void Append(const char* str){
int sz = strlen(str);
if (_size + sz > _capacity){
resever(_size + sz);
}
strcpy(_str + _size, str);
_size += sz;
}
void Resize(size_t n, char c = '\0'){
if (n > _size){
if (n > _capacity){
resever(n);
}
memset(_str + _size, c, n - _size);
}
_size = n;
_str[_size] = '\0';
}
void Insert(size_t pos, char c){
assert(pos <= _size);
if (_size == _capacity){
if (_capacity == 0){
_str = new char[15];
}
else{
resever(2 * _capacity);
}
}
int end = _size;
while (end >= pos){
_str[end+1] = _str[end ];
end--;
}
_str[pos] = c;
_size++;
}
void Insert(size_t pos, char* str){
assert(pos <= _size);
int len = strlen(str);
if (_size+len > _capacity){
resever(_size + len);
}
int end = _size;
while (end+len >= pos+len){
_str[end+len ] = _str[end];
end--;
}
for (int i = 0; i < len; i++){
_str[pos] = str[i];
pos++;
}
_size += len;
}
void Erase(size_t pos, size_t n){
assert(pos>0);
if (pos + n > _size){
_size = pos;
_str[_size] = '\0';
}
else{
int i = _size-pos;
while (i--){
_str[pos] = _str[pos + n];
pos++;
}
_str[_size - n] = '\0';
_size -= n;
}
}
size_t Find(char c, size_t pos = 0){
for (pos = 0; pos < _size;pos++){
if (c == _str[pos]){
return pos;
}
}
return -1;
}
size_t Find(char* str, size_t pos = 0){
assert(str);
for (pos = 0; pos < _size; pos++){
if (str[0] == _str[pos]){
for (int i = 0; i < strlen(str)&&pos<_size; i++){
if (str[++i] != _str[++pos]){
continue;
}
if (i==strlen(str)-1)
return pos-strlen(str)+1;
}
}
}
if (pos == _size){
return -1;
}
}
private:
size_t _size;
size_t _capacity;
char* _str;
};
int main(){
String s;
s.Append("adsyghjghjghjghjggfydtydtd");
/*s.Resize(4, 'K');*/
s.PrintfString();
cout << endl;
/*String s2(s);
s2.PrintfString();
String s3 = s2;
s3.PrintfString();
s3.Insert(2, 'B');
s3.PrintfString();
cout << endl;*/
s.Insert(3,"ADSd" );
s.PrintfString();
cout << endl;
String s3 = s;
size_t q=s3.Find("D打算带S");
cout << q << endl;
system("pause");
return 0;
}