Nghiên cứu lớp lớp String

Một phần của tài liệu Lập trình hướng đối tượng (Trang 98 - 105)

- Mục đích của nghiên cứu lớp String

+ Tạo ra lớp String để tạo ra các thao tác tự nhiên đối với chuỗi ký tự.

+ Nghiên cứu kỹ các constructor và các toán tử. + Tìm hiểu về nguyên tắc cấp phát động cho chuỗi ký tự. 7.1. Nhận xét class String { private: char *text; int len; public: String() {len=0;text=NULL;} String(const char *S); String(const String &S);

~String() {if (len!=-1) delete [] text;} ...

* Tác dụng của các constructor

- Một đối tợng String có 3 cách khởi tạo tờng minh String S1; // Dùng constructor String(); String S2("Hello");

// Dùng constructor khởi tạo String(const char*) String S3(S2);

// Dùng constructor sao chép String(const String&) - Tuy nhiên, có thể viết các constructor khởi tạo và constructor sao chép không tờng minh

String S2="Hello"; String S3=S2;

- Thậm chí trong đa số trờng hợp phép gán sau khai báo là chấp nhận đợc:

String S2,S3;

S2="Hello"; // ít an toàn, nên dùng thêm toán tử sao

chép sau đây:

operator = (const char*)

S3=S2; // an toàn hơn nếu vế phải chỉ có 1 đối tợng.

Nếu vế phải là một biểu thức giữa các đối tợng (giả sử đã định nghĩa các phép toán trong biểu thức) thì phép gán trên là sai. Nghĩa là constructor sao chép không tự giải thích đ- ợc trờng hợp này, và trong trờng hợp này cần dùng toán tử sao chép:

operator = (const String &)

Ví dụ: Với giả thiết lớp có các constructor đã nêu, thêm toán tử cộng 2 đối tợng String và các toán tử tải bội vào/ra. Bây giờ xét các lệnh:

String S1="Hello"; String S2="Hellen"; String S3="Peter"; String t1,t2; t1=S1+S2; t2=S1+S3; Kết quả: Hello Peter Hello Peter

cout<<t1<<endl; cout<<t2<<endl;

Thì kết quả khi chạy chơng trình không chính xác nữa.

* Nh vậy cần thiết phải bổ sung 2 toán sử sao chép const String& operator = (const String &S); (1) const String& operator = (const char *S); (2) Để cho phép thực hiện tờng minh các lệnh dạng S1="Hello"; // dùng toán tử (2)

S2=S1+S3; // dùng toán tử (1)

7.2. Cài đặt lớp String

Xây dựng Lớp String (mỗi đối tợng thuộc lớp là 1 chuỗi ký tự):

- Các constructor - sao chép

- Các toán tử để khởi tạo và sao chép: operator = - Các toán tử tải bội thân thiện

+ Vào/ ra

+ So sánh: operator ==, <=, >=, <, >(về độ dài) + Ghép chuỗi: operator + (phép cộng)

+ Phép cho truy nhập vào từng phần tử của chuỗi: operator [] #include <iostream.h> #include <conio.h> #include <string.h> #include <stdlib.h> #include <stdio.h> class String { private: char *text; int len;

public:

String(): len(-1),text(NullString) {} String(const char *S);

String(const String &S); // cau tu sao chep ~String() {if (len!=-1) delete [] text;}

const String& operator = (const String &S); const String& operator = (const char *S); char operator [] (int index) const;

char& operator [] (int index);

unsigned int length() const { return strlen(text); }

friend int operator == (const String &S1,const String &S2); friend int operator <= (const String &S1,const String &S2); friend String operator + (const String&,const String&); friend ostream& operator << (ostream &dout, String &S); friend istream& operator >> (istream &din, String &S); };

char *String::NullString=""; String::String(const char *S) { if(S==NULL)

{ len=0;

text = new char[1]; text[0]='\0'; } else

{ len=strlen(S);

text = new char[len+1]; strcpy(text,S); }

}

String::String(const String &S) { len=strlen(S.text);

text=new char[len+1]; strcpy(text,S.text);}

const String& String::operator=(const String &S) { const int len1 = strlen(S.text);

if (this!=&S)

{ if(len1>=len) { if(len!=-1) delete [] text; len=len1;

text=new char[len+1]; } strcpy(text,S.text);

}

return *this;}

const String& String::operator=(const char *S) { if (S==NULL) S="";

const int len1 = strlen(S);

{ if(len1>=len) { if(len!=-1) delete[] text; len=len1;

text=new char[len+1]; } strcpy(text,S);

}

return *this;}

char String::operator [] (int index) const { if(index <0 || index > strlen(text))

{ cout<<"index out of range"; abort(); } return text[index]; }

char& String::operator [] (int index) { if(index <0 || index > strlen(text))

{ cout<<"index out of range"; abort(); } return text[index]; }

int operator == (const String &S1,const String &S2) { return strcmp(S1.text,S2.text)==0; }

{ int len1=strlen(S1.text); int len2=strlen(S2.text); return len1<=len2 ? 1:0; }

String operator + (const String &S1,const String &S2) { String S;

S.len=S1.len + S2.len; S.text = new char[S.len+1]; strcpy(S.text,S1.text); strcat(S.text,S2.text); return S; }

ostream& operator << (ostream &dout, String &S) { dout<<S.text;

return dout; }

istream& operator >> (istream &din, String &S) { char str[2048]; gets(str); S.len=strlen(str); S.text=new char[S.len+1]; strcpy(S.text,str); return din; } int main() { clrscr(); String S1; String S2("Hello"); String S3(S2); String R; // String()

String S="Hello "; // String(const char*) String T=S; // String(const String&) R=T; // operator = (const String &) S="World"; // operator = (const char*)

R[0]='J'; // operator[]cho phep saochep ky tu S=T+S;

cout<<S; getche(); return 0; }

chơng 3:Sự kế thừa - inheritance

Bài 1. Sự tơng ứng trong kế thừa

Một phần của tài liệu Lập trình hướng đối tượng (Trang 98 - 105)

Tải bản đầy đủ (DOC)

(174 trang)
w