注意事项:
对于C语言字符串char*,必须在末尾置'\0';
对指针操作时,必须考虑指针为NULL的情况,对strcpy,strcat等库函数调用也一样;
对指针重新赋值前必须调用delete,同一块内存不能调用两次delete;
返回对象的成员函数要区分返回的是当前对象还是新对象,即函数返回类型是否要取地址(&)
关于迭代器更新一点:
String* sp = new String("hello,world!");
String::iterator it = sp;
迭代器begin()指向String类首字符'h',end()指向末尾字符'!'之后一位的空字符'\0'.
顺序迭代:
for (it = sp->begin(); it < sp->end(); it++)
cout << *it;
逆序迭代不能使用for循环(for循环不能输出begin()位置的元素),而且必须用前缀运算--it:
it = sp->end();
while(it > sp->begin())
cout << *--it;
再更新一下比较操作符“==”,见String.cpp具体实现
String.h
#ifndef STRING_H
#define STRING_H
#include <iostream>
class String {
public:
String();
String(const char* str);
~String();
int length()const;
char* toString()const;
char* c_str()const; //返回一个C风格字符串
String& insert(const char ch, const int n); //在下标n处插入字符
String& remove(const int n); //删除下标n处字符
String& remove(const int start, const int nChars); //删除start开始的nChars个字符
char operator[](const int n) const;
//必须对流用friend
friend std::ostream & operator<<(std::ostream & os, const String & str); //友元函数重载<<操作符
friend std::istream & operator>>(std::istream & is, const String & str); //友元函数重载>>操作符
int compare(const String &lhs, const String &rhs)const; //比较
bool operator==(const String &str)const;
bool operator!=(const String &str)const;
bool operator>(const String &str)const;
bool operator<(const String &str)const;
String& operator+=(const String &str);
String operator+(const String &str)const;
String& operator=(const String &str);
String(const String &str); //复制构造函数
//返回迭代器的成员函数要放在迭代器类定义后面
// iterator begin() const {
// return iterator(this, 0);
// }
//
// iterator end() const {
// return iterator(this, len);
// }
private:
int len;
char* data;
/**迭代器
* 使用方法:
* String* sp = new String(s);
* 1.
* String::iterator it;
* it = sp;
*
* 2.
* String::iterator it1(sp);
*
*迭代器范围:
* (it<=end()-1);
* (it>=begin());
* 对于+ -运算没有检查边界
*/
public:
class iterator {
public:
iterator() {
it = NULL;
index = 0;
}
iterator(const iterator &rhs) {
it = rhs.it;
index = rhs.index;
}
iterator(const String *sp) {
it = sp;
index = 0;
}
iterator(const String *sp, int n) {
it = sp;
index = n;
}
~iterator() {
// delete it;//!!!!!!不能在迭代器调用delete
it = NULL;
}
char operator*() {
return *(it->data + index);
}
iterator operator++(int) {//注意前缀运算符的&,后缀运算符无&(返回新的迭代器,即++之前的迭代器)
iterator copy(*this);
operator++();
return copy;
}
iterator& operator++() {
if (it == NULL) {
std::cout << "迭代器未初始化!程序退出!\n";
exit(1);
}
index++;
if (index > it->len)
it = NULL;
return *this;
}
iterator operator--(int) {
iterator copy(*this);
operator--();
return copy;
}
iterator& operator--() {
if (it == NULL) {
std::cout << "迭代器未初始化!程序退出!\n";
exit(1);
}
index--;
if (index > it->len || index < 0)//越界
it = NULL;
return *this;
}
bool operator==(const iterator &rhs) {
if (it != rhs.it) {
std::cout << "不同String迭代器!程序退出!==\n";
exit(1);
}
return (it == rhs.it && index == rhs.index);
}
bool operator!=(const iterator &rhs) {
if (it != rhs.it) {
std::cout << "不同String迭代器!程序退出!!=\n";
exit(1);
}
return !(*this == rhs);
}
bool operator<(const iterator &rhs) {
if (it != rhs.it) {
std::cout << "不同String迭代器!程序退出!<\n";
exit(1);
}
return (index < rhs.index);
}
bool operator<=(const iterator &rhs) {
if (it != rhs.it) {
std::cout << "不同String迭代器!程序退出!<=\n";
exit(1);
}
return (index <= rhs.index);
}
bool operator>(const iterator &rhs) {
if (it != rhs.it) {
std::cout << "不同String迭代器!程序退出!>\n";
exit(1);
}
return (index > rhs.index);
}
bool operator>=(const iterator &rhs) {
if (it != rhs.it) {
std::cout << "不同String迭代器!程序退出!>=\n";
exit(1);
}
return (index >= rhs.index);
}
iterator operator+(const int k) {
if (it == NULL) {
std::cout << "迭代器未初始化!程序退出!\n";
exit(1);
}
return iterator(it, index + k);
}
iterator operator-(const int k) {
if (it == NULL) {
std::cout << "迭代器未初始化!程序退出!\n";
exit(1);
}
return iterator(it, index - k);
}
// friend class String;
private:
const String* it;
int index;
};
iterator begin() const {
return iterator(this, 0);
}
iterator end() const {
return iterator(this, len);
}
};
#endif /* STRING_H */
String.cpp
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
#include "String.h"
#include <string.h>
#include <stdlib.h>
String::String() {
data = NULL;
len = 0;
}
String::String(const char* str) {
if (str == NULL) {
data = NULL;
len = 0;
} else {
len = strlen(str);
data = new char[len + 1];
strcpy(data, str);
data[len] = '\0';
}
}
String::~String() {
if (data != NULL) {
delete []data;
data = NULL;
}
}
inline int String::length()const {
return len;
}
char* String::toString()const {
char* str = new char[len + 1];
if (data != NULL)
strcpy(str, data);
str[len] = '\0';
return str;
}
char* String::c_str()const {
return toString();
}
String& String::insert(const char ch, const int n) {
int i;
if (n < len)
i = n;
if (n > len - 1)
i = len;
if (n < 0)
i = 0;
len++;
char* str = new char[len + 1];
for (int j = 0; j < i; j++)
str[j] = *(data + j);
str[i] = ch;
for (int j = i; j < len; j++)
str[j + 1] = *(data + j);
str[len] = '\0';
delete []data;
data = str;
return *this;
}
String& String::remove(const int n) {
return remove(n, 1);
}
String& String::remove(const int start, const int nChars) {
if (start < 0 || nChars <= 0 || start > (len - 1))
return *this;
int i;
if (start + nChars < len)
i = nChars;
else
i = len - start;
len -= i;
for (int j = start; j < len; j++)
*(data + j) = *(data + (j + i));
*(data + len) = '\0';
return *this;
}
char String::operator[](const int n) const {
if (n > (len - 1) || n < 0) {
std::cout << "超出边界!程序结束\n";
exit(1);
}
return *(data + n);
}
std::ostream & operator<<(std::ostream & os, const String & str) {
os << str.toString();
return os;
}
std::istream & operator>>(std::istream & is, const String & str) {
is >> str.toString();
return is;
}
int String::compare(const String& lhs, const String& rhs) const {
int n = (lhs.len < rhs.len ? lhs.len : rhs.len);
for (int i = 0; i < n; i++) {
if (lhs[i] > rhs[i])
return 1;
if (lhs[i] < rhs[i])
return 0;
}
if (lhs.len > rhs.len)
return 1;
if (lhs.len < rhs.len)
return 0;
return -1; //==
}
bool String::operator==(const String &str)const {
if (len != str.length())
return false;
if (len == 0)
return true;
//忘了检查边界,注释掉这几行,改用最后一行
//int i = 0;
//while (*(data + i) == *(str.data + i))
// i++;
//if (len == (i - 1))
// return true;
//return false;
//或者改成这几行
//int i = 0;
//while (*(data + i) == *(str.data + i)) {
// i++;
// if (i == len)
// return true;
//}
//return false;
return (compare(*this, str) == -1);
}
bool String::operator!=(const String &str)const {
return !(*this == str);
}
bool String::operator>(const String &str)const {
return (compare(*this, str) == 1);
}
bool String::operator<(const String &str)const {
return (compare(*this, str) == 0);
}
String& String::operator+=(const String &str) {
if (str.length() == 0)
return *this;
len = len + str.length();
char* newstr = new char[len + 1];
if (data != NULL) {
strcpy(newstr, data);
delete []data;
}
strcat(newstr, str.data);
newstr[len] = '\0';
data = newstr;
return *this;
}
String String::operator+(const String &str)const {
String s1;
if (len == 0 && str.length() == 0)
return s1;
s1.len = len + str.length();
s1.data = new char[s1.len + 1];
if (data != NULL)
strcpy(s1.data, data);
if (str.data != NULL)
strcat(s1.data, str.data);
*(s1.data + s1.len) = '\0';
return s1;
// s1 += *this;//低效
// s1 += str;
// return s1;
}
String& String::operator=(const String &str) {
delete []data;
data = new char[str.length() + 1];
len = str.length();
if (str.data != NULL)
strcpy(data, str.data);
data[len] = '\0';
return *this;
}
String::String(const String& str) {
data = new char[str.length() + 1];
len = str.length();
if (str.data != NULL)
strcpy(data, str.data);
data[len] = '\0';
}
测试程序
#include <cstdlib>
#include "String.h"
#include <vector>
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
String s("hello,world!");
cout << s << endl;
s.insert('t', 0);
cout << s << endl;
s.insert('t', 13);
cout << s << endl;
s.remove(0);
cout << s << endl;
s.remove(12);
cout << "s:" << s << endl;
cout << "s.c_str():" << s.c_str() << endl;
cout << "s.toString():" << s.toString() << endl;
cout << "s.length():" << s.length() << endl;
cout << "s[11]:" << s[11] << endl;
cout << "s[4]:" << s[4] << endl;
String s1("hello,world!");
cout << "s:" << s << endl;
cout << "s1:" << s1 << endl;
cout << "(s==s1):" << (s == s1) << endl;
cout << "(s!=s1):" << (s != s1) << endl;
cout << "(s>s1):" << (s > s1) << endl;
cout << "(s<s1):" << (s < s1) << endl;
String s2 = "sttt";
String s3 = "ffffq";
// s3 = "sttt";
cout << "s2:" << s2 << endl;
cout << "s3:" << s3 << endl;
cout << "(s2==s3):" << (s2 == s3) << endl;
cout << "(s2!=s3):" << (s2 != s3) << endl;
cout << "(s2>s3):" << (s2 > s3) << endl;
cout << "(s2<s3):" << (s2 < s3) << endl;
cout << "('a'<'b'):" << ('a' < 'b') << endl;
s2 += s3;
cout << "s2:" << s2 << endl;
String s4;
// s4 += s2;
// s4 = s2;
// s4 = s3;
cout << "s4:" << s4 << endl;
cout << "s4.length():" << s4.length() << endl;
cout << "s4+s2:" << s4 + s2 << endl;
cout << "s2+s4:" << s2 + s4 << endl;
cout << "s4+s2 len:" << (s4 + s2).length() << endl;
String s5(s4);
cout << "s4:" << s4 << endl;
cout << "String (s5(s4)):" << s5 << endl;
String s0(s4 + s);
cout << "String s0(s4+s):" << s0 << endl;
s4 = s4;
s5 = s;
cout << "s4 = s4:" << s4 << endl;
cout << "s5 = s:" << s5 << endl;
String* sp = new String;
String* sp1 = new String(*sp);
*sp = s0;
cout << "sp:" << *sp << sp->length() << endl;
cout << "sp1:" << *sp1 << sp1->length() << endl;
delete sp1;
sp1 = new String;
delete sp1;
delete sp;
sp = NULL;
sp1 = NULL;
String s6;
String s7 = "";
cout << "s6:" << s6 << endl;
cout << "s7:" << s7 << endl;
cout << "(s6==s7):" << (s6 == s7) << endl;
cout << "(s6>s7):" << (s6 > s7) << endl;
cout << "(s6<s7):" << (s6 < s7) << endl;
string str1;
string str2 = "";
str1.push_back('f');
cout << "(str1 == str2):" << (str1 == str2) << endl;
cout << "sizeof(string):" << sizeof (string) << endl;
cout << "sizeof(String):" << sizeof (String) << endl;
String sa[10];
cout << "String sa[10];:" << sizeof (sa) << endl;
String s8("hello,world!");
cout << s8 << endl;
s8.remove(5, 5);
cout << s8 << endl;
cout << s8.length() << endl;
char* cp = new char[2];
cp[0] = '\0';
delete []cp;
cp = NULL;
cp = new char[2]; //要想再用此指针,此句不能少
cp[0] = 'g';
cp[1] = 'g';
delete []cp;
cp = NULL;
delete []cp;
delete cp;
String* sp2 = new String(s);
cout << "*sp2:" << *sp2 << endl;
String::iterator it;
it = sp2;
cout << "*it:" << *it << endl;
cout << "*++it:" << *++it << endl;
for (; it < sp2->end(); it++)
cout << *it;
cout << endl;
String::iterator it1(sp2);
// it1=sp2;
for (it1 = sp2; it1 < sp2->end(); it1++)
cout << *it1;
cout << endl;
for (it1 = sp2->end(); it1 > sp2->begin(); --it1)//逆序迭代不能用for循环,应该用while
cout << *it1;//不能打印首元素
cout << endl;
cout << *it1 << endl;
cout << *++it1 << endl;
cout << *++it1 << endl;
it1++;
cout << *it1 << endl;
cout << *(it1++) << endl; //*(it1++)不能解析??需要去掉定义中的地址符& !!
cout << *(it1 + 1) << endl;
cout << *(it1 - 1) << endl;
cout << *(it1 - 1) << endl;
cout << *(it1 + 1) << endl;
for (it1 = sp2->begin(); it1 <= sp2->end()-1; it1++)
cout << *it1;
cout << endl;
String::iterator it2(sp2);
return 0;
}