自己實現String類及其迭代器
阿新 • • 發佈:2018-12-11
注意事項:
對於C語言字串char*,必須在末尾置'\0';
對指標操作時,必須考慮指標NULL的情況,對strcpy,strcat等庫函式呼叫也一樣;
對指標重新賦值前必須呼叫delete,同一塊記憶體不能呼叫兩次delete;
返回物件的成員函式要區分返回的是當前物件還是新物件,即函式返回型別是否要取地址(&)
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 < -1)//-1表示在begin之前一位 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; // 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'; } 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--) 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; }