文章目录
- 前言
- 一、 clear函数
- 二、流提取(<<)和流插入(>>)运算符重载
- 三、 >、<、==、<=、>=、!=的运算符重载
- 四、赋值运算符(=)重载
- 总结
前言
模拟实现string类: clear函数、流提取(<<)和流插入(>>)运算符重载、>、<、==、<=、>=、!=的运算符重载、赋值运算符(=)重载等的介绍
string类的上半部分:模拟实现string类对象上半部分
一、 clear函数
- 清除字符串的内容,本质上就是让字符串大小置为0, 将0处的字符置为’\0’
void clear()
{_size = 0;_str[_size] = '\0';
}
二、流提取(<<)和流插入(>>)运算符重载
- 流提取,就是循环打印每个字符,可以使用【】运算符重载和范围for语法糖
- 流插入,这里采用临时字符数组的形式:
-
- 首先,先检查并跳过输入字符串之前的空格或换行,然后创建一个128个字节空间的临时字符数组
-
- 然后,不断读取字符,并插入到字符数组中去,当字符数组中存储127个字符后,将最后一个空间置为’\0’
-
- 然后,将使用+=运算符重载将字符数组插入到string类中,循环执行,直到字符串结束
-
- 最后,若下标值不为0,将字符数组末置为’\0’,并+=到string类中。
这样做的好处是,可以减少string类开辟空间的次数, 提高性能。
// 流提取
ostream& operator<<(ostream& out, string& s)
{for (auto ch : s){out << ch;}//for (size_t i = 0; i < s.size(); i++)//{// out << s[i];//}return out;
}// 流插入
istream& operator>>(istream& in, string& s)
{// 检查并跳过输入字符串之前的空格或者换行char ch = in.get();while (ch == ' ' || ch == '\n'){ch = in.get();}char buff[128];int i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[i] = '\0';s += buff;i = 0;}ch = in.get();}if (i != 0){buff[i] = '\0';s += buff;}return in;
}
测试:
void Test_string7()
{hhb::string s1("hello world");cout << s1 << endl;hhb::string s2;cin >> s2;cout << s2 << endl;
}
- 只开辟了两次空间。
三、 >、<、==、<=、>=、!=的运算符重载
- 可以循环遍历字符串内容,比较每个字符,根据对应规则返回布尔值,若跳出循环,则比较长度,长的字符大
- 也可以是memcmp函数进行比较,memcmp函数大于返回大于0的值,小于返回小于0的值,等于,返回0。
- 只用书写< 和 == 的逻辑,其他的可以复用。
// < 运算符重载
// hello hello // false
// hello helloxxx // true
// helloxxx hello // false
/*bool operator< (string& s)
{size_t i1 = 0;size_t i2 = 0;while (i1 < _size && i2 < s._size){if (_str[i1] < s._str[i2]){return true;}else if (_str[i1] > s._str[i2]){return false;}else{++i1;++i2;}}if (_size < s._size){return true;}else{return false;}
}*/bool operator< (string& s) const
{int ret = memcmp(_str, s._str, _size > s._size ? _size : s._size);return (ret < 0);
}bool operator== (string& s) const
{return _size == s._size&& memcmp(_str, s._str, _size) == 0;
}bool operator> (string& s) const
{return !(*this < s || *this == s);
}bool operator<= (string& s) const
{return !(*this > s);
}bool operator>= (string& s) const
{return !(*this < s);
}bool operator!= (string& s) const
{return !(*this == s);
}
测试:
void Test_string8()
{hhb::string s1("hello");hhb::string s2("helloxxxx");cout << (s1 < s2) << endl;cout << (s1 > s2) << endl;cout << (s1 != s2) << endl;cout << (s1 == s2) << endl << endl;hhb::string s3("helloxxxx");hhb::string s4("hello");cout << (s3 < s4) << endl;cout << (s3 > s4) << endl;cout << (s3 != s4) << endl;cout << (s3 == s4) << endl << endl;hhb::string s5("hello");hhb::string s6("hello");cout << (s5 < s6) << endl;cout << (s5 > s6) << endl;cout << (s5 != s6) << endl;cout << (s5 == s6) << endl << endl;}
四、赋值运算符(=)重载
-
- 开辟和s一样空间的大小,进行深拷贝,把字符串内容拷贝到空间中去, 然后释放原来的空间内容,将字符串指向新开辟的空间 ,最后拷贝字符大小和字符串的空间。
-
- 在=运算符重载函数中使用传入的类对象创建临时的类对象,调用std的交换函数,交换临时对象和原来的对象内容。完成赋值,并且当函数结束,临时对象会自动调用析构函数。
-
- 直接传值调用,直接创建临时对象,并与临时对象交换内容。完成赋值。
// =运算符重载
/*string& operator= (const string& s)
{char* tmp = new char[s._capacity + 1];delete[] _str;memcpy(tmp, s._str, s._size);_str = tmp;_size = s._size;_capacity = s._capacity;return *this;}*//*string& operator= (const string& s)
{if (this != &s){string tmp(s);std::swap(_str, tmp._str);std::swap(_size, tmp._size);std::swap(_capacity, tmp._capacity);}return *this;}*/void swap(string& s)
{std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}string& operator= (string tmp)
{swap(tmp);return *this;}
测试:
void Test_string9()
{hhb::string s1("hello world");hhb::string s2("ladys and gentleman");s1 = s2;cout << s1 << endl;
}
总结
模拟实现string类: clear函数、流提取(<<)和流插入(>>)运算符重载、>、<、==、<=、>=、!=的运算符重载、赋值运算符(=)重载等的介绍