<三>自己实现string,加入迭代器功能
迭代器的功能:
提供一种统一的方式,来透明的遍历容器
理解 begin()方法,end()方法, ++ , * 的用处
其中 C++11 中提供的foreach的方式,其底层还是通过迭代器来进行遍历的.
#include <iostream>
using namespace std;
class MyString2 {
public:
//构造函数
MyString2(const char * pSource = nullptr) {
if (pSource != nullptr) {
pString = new char[strlen(pSource) + 1];
strcpy(pString, pSource);
}
else {
pString = new char[1];
pString[0] = '\0';
}
cout << "MyString构造函数,对象地址=" << this << endl;
}
//拷贝构造
MyString2(const MyString2 & _rValue) {
pString = new char[strlen(_rValue.pString) + 1];
strcpy(pString, _rValue.pString);
cout << "MyString拷贝构造函数" << endl;
}
//赋值函数
MyString2 & operator=(const MyString2 & _rValue) {
if (this == &_rValue) {
return *this;
}
delete[] this->pString;
this->pString = nullptr;
char * _tpString = new char[strlen(_rValue.pString) + 1];
strcpy(_tpString, _rValue.pString);
cout << "MyString赋值函数" << endl;
}
//可编辑
char & operator[](int index) {
int len = strlen(this->pString);
if (index<0) { return pString[0]; }
else if (index>len) { return pString[index]; }
else { return pString[index]; }
}
//不可编辑
const char operator[](int index) const {
int len = strlen(this->pString);
if (index<0) { return pString[0]; }
else if (index>len) { return pString[index]; }
else { return pString[index]; }
}
bool operator>(const MyString2 & _rValue) const {
return strcmp(this->pString, _rValue.pString)>0;
}
bool operator<(const MyString2 & _rValue) const {
return strcmp(this->pString, _rValue.pString)<0;
}
bool operator==(const MyString2 & _rValue) const {
return strcmp(this->pString, _rValue.pString) == 0;
}
int length() const {
return strlen(this->pString);
}
~MyString2() {
if (this->pString != nullptr) {
delete[] this->pString;
this->pString = nullptr;
cout << "MyString析构函数" << this << endl;
}
}
const char * c_str() const { return this->pString; }
//给Mystring 设计迭代器
class Iterator {
public:
Iterator(char * _p=nullptr):p(_p) {
this->p = _p;
}
char & operator*() {
return *p;
}
//前置++
void operator++() {
p++;
}
//
bool operator!=(const Iterator & _val) {
return p!=_val.p;
}
private:
char * p;
};
// begin() 返回的 用MyString的首元素地址,通过Iterator封装一下
Iterator begin() const {
return Iterator(this->pString);
}
// end() 返回的是 用 MyString 的最尾元素的下一个地址 再用Iterator封装一下
Iterator end() const {
return Iterator(this->pString+this->length());
}
private:
char * pString;
friend MyString2 operator+ (const MyString2 & s1, const MyString2 &s2);
friend ostream & operator<<(ostream & out, const MyString2 &s);
};
MyString2 operator+(const MyString2 & s1, const MyString2 &s2) {
/*
方式1 这段代码有 内存泄漏问题 tp 没有释放掉
int newLength = strlen(s1.pString) + strlen(s2.pString) + 1;
char *tp = new char[newLength + 1];//重新申请空间
strcpy(tp, s1.pString);
strcat(tp, s2.pString);
MyString s(tp);
cout << "operator+ = " << &s << endl;
return s;
*/
/*
方式2 对比方式1 效果更高
*/
MyString2 s;
int newLength = strlen(s1.pString) + strlen(s2.pString) + 1;
s.pString = new char[newLength + 1];//重新申请空间
strcpy(s.pString, s1.pString);
strcat(s.pString, s2.pString);
cout << "operator+ = " << &s << endl;
return s;
}
ostream & operator<<(ostream & out, const MyString2 &s) {
cout << s.pString << endl;
return out;
}
void test2() {
MyString2 s1("12345");
MyString2 s2("6789ABC");
cout << s1 << endl;
cout << s2 << endl;
MyString2 s3 = s1 + s2;
cout << s3 << endl;
cout << "s3 = " << &s3 << endl;
for (int i = 0; i < s3.length(); i++) {
cout << s3[i] << endl;
}
cout << "--------------------" << endl;
s3[0] = 'W';
for (int i = 0; i < s3.length(); i++) {
cout << s3[i] << endl;
}
const MyString2 s4("hello");
for (int i = 0; i < s4.length(); i++) {
cout << s4[i] << endl;
}
cout << "------iterator Begin------" << endl;
MyString2::Iterator it_begin = s4.begin();
MyString2::Iterator it_end = s4.end();
for ( ;it_begin!=it_end; ++it_begin) {
cout << *it_begin <<" ";
}
cout << endl;
cout << "------iterator End------" << endl;
}
int main() {
test2();
system("pause");
return 0;
}