尝试编写的错误总结
1. 对于 insert 的实现,找出下面代码的冗余
第一 使用了一个tmp来承接会被 \0 冲掉的位置的字符,实际上可以直接利用strncpy,
第二 while循环的循环结束调节并没有把pos位置后面的那个字符进行移动,
存在隐藏bug
string& insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);char tmp = _str[pos];reserve(_size + len);size_t end = _size + len;while (end > (pos + len)){_str[end] = _str[end - len];end--;}strcpy(_str + pos, str);_str[pos + len] = tmp;_size += len;return *this;}
可以将代码改写成下述 形式
void insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len >= _capacity){reserve(_size + len);}size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];end--;}strncpy(_str + pos, str, len);_size += len;}
上课笔记:
1. 对于string类的 迭代器 iterator,确实可以直接使用指针实现,
但并不代表 STL中的中的iterator就是指针类型
2. 需要针对在创建时,重载一个const版本的成员函数
2.1 iterator begin(),如下形式
typedef char* iterator;iterator begin(){return _str;}typedef const char* const_iterator;const_iterator begin() const{return _str;}
2.2 将 [ ] 这个运算符重载成两个版本的,如下形式
char& operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}
3. 几个函数在string功能的模拟实现中的特殊之处
3.1 clear() 的功能,清除 string 中的数据,
特殊:在调用流插入这个运算符时,可以先调用 clear(),
保证流插入的数据将会覆盖原数据
3.2 get(),无论缓冲区有什么字符,直接通过这个函数获得并返回
特殊:在模拟实现 >> 这个流插入运算符时,通过与get()配合,
实现将任意字符作为流插入结果的分隔符
3.3 流插入的实现,既要保证开空间的次数少,又要保证不浪费太多堆上的空间
特殊实现如下:
istream& operator>>(istream& in, string& s){s.clear();char ch;ch = in.get();char buff[128];size_t i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[127] = '\0';s += buff;i = 0;}//in >> ch;ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}return in;}
4. 复用函数的嵌套顺序
4.1 insert 实现了之后实现 push_back,再实现 += 字符 运算符
4.2 insert实现了之后实现 append,在实现 += 字符串 运算符
4.3 swap实现了之后实现拷贝构造