簡單版的String類,旨在說明>> <<重載
#include <iostream> //#include <cstring>//包含char*的字符串處理函數 using namespace std; class String { public: String(){p=NULL;} String(char *str); void diaplay(); friend bool operator>(String &str1,String &str2);//重載>操作符 friend ostream & operator <<(ostream&,String &str); friend istream & operator >>(istream&,String &str); private: char *p; }; String::String(char *str) { p=str; } void String::diaplay() { cout<<p; } bool operator>(String &str1,String &str2) { if (strcmp(str1.p,str2.p)>0) { return true; } else return false; } ostream& operator <<(ostream& output,String &str) { output<<str.p; return output; } istream& operator >>(istream& input,String &str) { //input>>str.p;//沒有分配空間,無法讀入。 str.p=new char[256]; input>>str.p; return input;// // char q[256]; // input>>q; // //p.length =strlen(q); // str.p=new char[strlen(q)+1]; // strcpy(str.p,q); // return input; } int main() { String str1("Hello,pig!"),str2; cin>>str2; str1.diaplay(); bool b=str1>str2; cout<<'\n'<<b<<endl; cout<<str2<<endl; }
重載>> <<函數只能作為類的類的友元函數,其形式如下:
istream& operator >>(istream& ,自定義類 &);
ostream& operator <<(ostream& ,自定義類 &);
重載運算法作為類成員函數還是類友元函數區別:
1 作為類成員函數必須滿足運算表達式第一個參數是一個類對象,而且返回值與該對象同類型。
故一般將單目操作符重載為成員函數,雙目操作符重載為友元函數。
String 類較完整實現:
#include <iostream> //#include <cstring>//包含char*的字符串處理函數 using namespace std; class String { public: String(){p=NULL;len=0;} String(int); String(char *str); String (String&); ~String(){delete[] p;} void Clear();//清空本串 int mystrlen(); bool IsEmpty();//判斷本串是否為空 String Substr(int index,int count);//從index開始提取count個字符的字串 int Find(char c,int start);//從下標start開始找到c后,返回字符c 在本串的下標 char & operator [](int i);//重載[]操作符 operator char *();//將String類對象轉換為普通字符串 friend bool operator>(String &str1,String &str2);//重載>操作符 friend ostream & operator <<(ostream&,String &str); friend istream & operator >>(istream&,String &str); private: char *p;//字符串指針 int len;//字符串長度,不包含最后的\0 }; String::String(int length) { len=length; p=new char[length+1]; } String::String(char *str) { if (str==NULL) { len=0; p=NULL; } else { len=strlen(str); p=new char[len+1]; strcpy(p,str);//深拷貝 } //p=str;//只寫這個是淺拷貝,只拷貝了指針 } String::String(String &other) { len=other.len; p=new char[len+1]; strcpy(p,other.p); } bool String::IsEmpty() { return (!this->len); } void String::Clear() { if (!IsEmpty()) { delete[]p; len=0; } } int String::mystrlen() { return len; } int String::Find(char c,int start) { int i; if (start>len) cout<<"超出范圍"<<endl; //return NULL; else { for (i =start;i<len;++i) { if (p[i]==c) break; } return i; } } String String::Substr(int index,int count) { if (index+count>len) cout<<"超出范圍"<<endl; else { String str(count); str.len=count; for (int i=0;i<count;i++,index++) str.p[i]=p[index]; str.p[count]='\0'; return str; } } char & String::operator[](int i) { if (i<0||i>len-1) { cout<<"越界"<<endl; } else { return p[i]; } } //類型轉換 String::operator char *() { return (char *)p; } bool operator>(String &str1,String &str2) { if (strcmp(str1.p,str2.p)>0) { return true; } else return false; } ostream& operator <<(ostream& output,String &str) { output<<str.p; return output; } istream& operator >>(istream& input,String &str) { //input>>str.p;//沒有分配空間,無法讀入。 str.p=new char[256]; input>>str.p; return input;// //或者: // char q[256]; // input>>q; // str.p=new char[strlen(q)+1]; // strcpy(str.p,q); // return input; } int main() { String str3("hello"); int pos; cout<<"\n測試Find功能"<<endl; pos = str3.Find('e',0); cout<<str3<<endl; cout<<pos<<endl; cout<<"\n測試Substr功能"<<endl; cout<<str3.Substr(1,2)<<endl; cout<<"\n測試重載<< >>功能"<<endl; String c; cout<<"請輸入一段字符串"<<endl; cin>>c; cout<<c<<endl; cout<<"測試字符串C函數的應用"<<endl; String f(40); char *e = " this is a test"; char g[50]="hahahhah"; strcpy(f,e); //隱含執行了默認類型轉換(char *)f; cout<<f<<endl; strcat(g,f); cout<<g<<endl; cout<<"\n測試IsEmpty _strlen功能"<<endl; String d("tihs is a test"); if(d.IsEmpty()) cout<<"d 是空字符串"<<endl; else cout<<"d 非空字符串 \t長度:"<<d.mystrlen()<<endl; return 0; }
注意:C++標准庫中string類構造函數是淺拷貝,
string a="hello";
string b(a);
cout<<(void *)a[2]<<endl;
cout<<(void *)b[2]<<endl; 地址形同
注意:operator char *();//將String類對象轉換為普通字符串
是類型轉換函數的定義,即該類型可以自動轉換為const char*類型。
像是隱式類型轉換
不同於重載*,重載*應寫為 char operator * ();
因為運算符重載中有幾個運算符的返回值是有格式的(約定),如operator * 在重載時通常返回值是classType&或者const classType& 。
operator const char*() const是類型轉換函數的定義,即該類型可以自動轉換為const char*類型。至於最后一個const,那個大家都知道是對類成員的限制(不允許更改對象的狀態)
比如我們現在自定一個一個整型(MyInt),它允許在需要使用C++語言中的int類型時將MyInt類型轉換為int類型:
class MyInt {
public:
operator int () const;
private:
int elem;
};
MyInt::operator int () const
{
return elem;
}
就可以在需要使用int類型時使用MyInt。
需要記住,C++中沒有返回類型的函數有3個,構造函數、析構函數、類型轉換函數。
前兩個是不寫返回類型函數實現中也不允許出現return語句
最后一個則是不寫返回類型,但是必須返回對應類型的值,即必須出現return語句。
類型轉換中返回類型在operator后面在括號前面,且沒有參數。
函數運算符中是類型在operator 前面