Giáo trình Lập trình hướng đối tượng với C++

pdf 52 trang phuongnguyen 6690
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Lập trình hướng đối tượng với C++", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_voi_c.pdf

Nội dung text: Giáo trình Lập trình hướng đối tượng với C++

  1. LP TRÌNH H NG I T NG V I C++ Mét sè tiÖn Ých vµ më réng cña C++ so víi C MỤC TIÊU C ỦA BÀI NÀY GIÚP NG ƯỜI H ỌC  Nh p/xu t d li u s d ng toán t cin và cout  Vit chú thích trên m t dòng, khai báo bi n m i n ơi, c p phát và thu h i b nh ng s d ng toán new và delete,  Gi i các bài t p có s d ng k thu t ch ng hàm, thâm s ng m nh. A/ TÓM T ẮT LÝ THUY ẾT - C++ là m t s m i r ng c a C, do ó có th s d ng m t ch ươ ng trình biên d ch C++ d ch và th c hi n các ch ươ ng trình vi t b ng C - C yêu c u các chú thích n m gi a /* và */. C++ cho phép t o m t chú thích b t u bng “//” cho n h t dòng - C++ cho phép khai báo tu ý. Th m chí có th khai báo bi n trong ph n kh i t o ca câu lênh l p for - C++ cho phép truy n tham s cho hàm b ng tham chi u. iu này t ươ ng t nh ư truy n tham bi n cho ch ươ ng trình con trong ngôn ng l p trình PASCAL. Trong l i g i hàm ta dùng tên bi n và bi n ó s ưc truy n cho hàm qua tham chi u. iu ó cho phép thao tác tr c ti p trên bi n ưc truy n ch không ph i gián ti p qua bi n tr . - Toán t new và delete trong C++ ưc dùng qu n lý b nh ng thay vì các hàm c p phát ng c a C - C++ cho phép ng ưi vi t ch ươ ng trình mô t các giá tr ng m nh cho các tham s ca hàm, nh ó hàm có th ưc g i v i m t danh sách các tham s không . - Toán t “::” cho phép truy nh p bi n toàn c c khi ng th i s d ng bi n c c b và toàn c c cùng tên. - Có th nh ngh a các hàm cùng tên v i các tham s khác nhau. Hai hàm cùng tên s ưc phân bi t nh giá tr tr v và danh sách ki u các tham s . B. MỘT S Ố L ƯU Ý (Các l i th ưng g p, m t s thói quen l p trình t t )  Các l ỗi th ường g ặp  Quên óng */ cho các chú thích  Khai báo bi n sau khi bi n ưc s d ng  S d ng l nh return tr v giá tr nh ưng khi nh ngh a hàm l i mô t hàm ki u void ho c ngưc l i, quên câu l nh này trong tr ưng h p hàm yêu c u giá tr tr v .  Không có hàm nguyên m u cho các hàm  B qua kh i t o cho các bi n tham chi u  Thay i giá tr c a các h ng  To các hàm cùng tên, cùng tham s .  M ột s ố thói quen l ập trình t ốt  S d ng “//” tránh l i không óng */ khi chú thích n m g n trong m t dòng.  S d ng các kh n ng vào ra m i c a C++ ch ươ ng trình d c h ơn.  t các khai báo biên lên u kh i l nh.  Ch dùng t khoá inline v i các hàm “nh ”,”không ph c t p”.  S d ng con tr truy n tham s cho hàm khi c n thay i giá tr tham s , còn tham chi u dùng truy n các tham s có kích th ưc l n mà không có nhu c u thay i n i dung.  Tránh s d ng bi n cùng tên cho nhi u m c ch khác nhau trong ch ươ ng trình. Trang 1
  2. LP TRÌNH H NG I T NG V I C++ C/ BÀI T ẬP M ẪU Ví d  1: C++ ch p nh n hai ki u chú thích. Các l p trình viên b ng C ã quen v i cách chú thích b ng /* */. Trình biên d ch s b qua m i th n m gi a /* */. Xét ch ươ ng trình sau : CT1_1.CPP /* Ch ươ ng trình in các s t 0 n 9. 1. */ #include void main() { int I; for(I = 0; I void main() { int X, Y; cout<< "Nhap vao mot so X:"; Trang 2
  3. LP TRÌNH H NG I T NG V I C++ cin>>X; cout >Y; cout void menu() { cout 4”;cin>>lc; switch(lc) { case 1:cout >n; for(int i=0;i >a[i]; } for(i=0;i<n;i++) cout<<a[i]; Lời g ải Ch ươ ng trình b l i trong vòng for th hai do bi n m ng a không ưc nh ngh a. Mng a ưc khai báo trong vòng for th nh t ch có t m ho t ng trong vòng for ó mài thôi. Do v y, ch ươ ng trình không th bi t trong vòng l p for th hai. Chú ý Trang 3
  4. LP TRÌNH H NG I T NG V I C++ bi n nguyên i ưc khai báo trong dòng l nh for có v trí t ươ ng ươ ng v i vi c khai báo i bên ngoài for. Vì v y, trong vòng for th hai ta s d ng bi n i nh ưng ch ươ ng trình không báo l i. Ví d  5: Tìm l i sai cho các khai báo prototype hàm d ưi ây (các hài này ưc khai báo trong cùng m t ch ươ ng trình) int func1(int); // (1) float func1(int); // (2) int func1(float); //(3) void func1(int=0,int); //(4) void func2(int,int=0); //(5) void func2(int); //(6) void func2(float); //(7) Lời g ải: Trong nh ngh a ch ng hàm, trình biên d ch phân bi t các hàm b i ki u d li u tr ra c a hàm mà ch phân bi t b i danh sách tham s c a hàm. Do v y hàm 1 và hàm 2 b nh ngh a ch ng lên nhau và trình biên d ch báo l i. Gi a hàm 2 và hàm 3 không có li b i chúng khác nhau b i ki u d li u c a tham s . Trong hàm 4 ta ã s d ng sai cách truy n giá tr m c nh cho tham s . Không báo gi truy n giá tr m c nh cho mt tham s tr ưc m t tham s không ưc truy n giá tr ng m nh. Trong cách nh ngh a hai hàm 5 và 6 có s nh p nh ng. Khi ta g i hàm func2 v i tham s là m t s nguyên thì trình biên d ch không bi t là s g i hàm 5 hay hàm 6 b i vì c hai hàm này u ưc. Trong tr ưng h p này trình biên d ch c ng thông báo l i. Ví d ụ 6: Tìm l i sai(l i cú pháp và b nh ) cho ch ươ ng trình sau: int & refl() { int a=5; return a; } int & rè2(int a) { a++; return a; } int & ref3(int & a) { a++; return a; } int a=5; int &r1; int & r2=22; int &r3=a; int &r4=ref3(5); int &r5=ref3(a); Tr ả l ời: Trong các hàm có k t qu tr v là m t tham chi u, chúng ta luôn ph i chú ý r ng bi n ưc tr l i có giá tr là tham chi u không b xoá kho i b nh ch ươ ng trình khi k t thúc th c hi n hàm. Do v y hai hàm ref1 và ref2 là sai b i vì nó tr v tham chi u t i biên mà a l i là bi n c c b trong ref1 và là tham s trong ref2 ch ưc t o ra t m th i Trang 4
  5. LP TRÌNH H NG I T NG V I C++ trên stack khi g i hàm và xoá kh i stack khi k t thúc hàm. Hàm ref3 không có l i vì a là mt tham chi u t i m t bi n không n m trong hàm. Trong khái báo các tham chi u ph i ưc g n v i m t bi n nào ó trong b nh . Do vy các khai báo r1, r2 là sai. L i g i ref3(5) c ng là sai b i vì tham s cho hàm ph i là tham chi u n m t bi n, trong khi ó ta l i truy n vào h ng s . Ví d ụ 7: Cho bi t k t qu th c hi n ch ươ ng trình sau: #include int & foo(int &a,int b) { b+=a; if (b>5) a++; return a; } void main() { int i=2,j=4; int k=foo(i,j); k++; cout void hoanvi(int &a,int &b) { int tam=a; a=b; b=tam; } void main() { // Nhap du lieu int n; cout >n; //Cap phat bo nho cho mang int *a=new int(n); cout >a[i]; } // Sap xep for(i=0;i<n-1;i++) for(int j=i++;j<n;j++) Trang 5
  6. LP TRÌNH H NG I T NG V I C++ if (a[i]>a[j]) hoanvi(a[i],a[j]); // In ket qua cout #include #include void main() { int N; cout >N; int *P=new int[N]; if (P==NULL) { cout P[J]) { int Temp=P[I]; P[I]=P[J]; P[J]=Temp; } cout<<"\nMang sau khi sap xep\n"; for(I=0;I<N;++I) cout<<P[I]<<" "; delete []P; } kt qu Trang 6
  7. LP TRÌNH H NG I T NG V I C++ Ví d ụ 10: Ch ươ ng trình c ng hai ma tr n trong ó m i ma tr n ưc c p phát ng. Chúng ta có th xem m ng hai chi u nh ư m ng m t chi u nh ư hình 1.2 dưi ây Hình 1.2: M ng hai chi u có th xem nh ư m ng m t chi u. Gi X là m ng hai chi u có kích th ưc m dòng và n c t. A là m ng m t chi u t ươ ng ng. Nu X[i][j] chính là A[k] thì k = i*n + j Chúng ta có ch ươ ng trình nh ư sau : CT1_10.CPP #include #include //prototype void AddMatrix(int * A,int *B,int*C,int M,int N); int AllocMatrix(int A,int M,int N); void FreeMatrix(int *A); void InputMatrix(int *A,int M,int N,char Symbol); void DisplayMatrix(int *A,int M,int N); int main() { int M,N; int *A = NULL,*B = NULL,*C = NULL; clrscr(); cout >M; cout >N; //C p phát vùng nh cho ma tr n A if (!AllocMatrix(&A,M,N)) { //endl: Xu t ra kí t xu ng dòng (‘\n’) cout<<"Khong con du bo nho!"<<endl; return 1; } //C p phát vùng nh cho ma tr n B if (!AllocMatrix(&B,M,N)) { Trang 7
  8. LP TRÌNH H NG I T NG V I C++ cout >A[I*N+J]; } } //Hi n th ma tr n void DisplayMatrix(int *A,int M,int N) { Trang 8
  9. LP TRÌNH H NG I T NG V I C++ for(int I=0;I<M;++I) { for(int J=0;J<N;++J) { out.width(7);//Hien thi canh le phai voi chieu dai 7 ky tu cout<<A[I*N+J]; } cout<<endl; } } kt qu D/ BÀI T ẬP T Ự GI ẢI Câu h ỏi tr ắc nghi ệm Câu 1: Cho bi t giá tr c a k sau khi th c hi n on ch ươ ng trình int i=5,k; { int i=6; ::i ; k=i; } k-=i; Vi các k t qu : a) k=0 b) k=1 c) k=2 d)k=3 Câu 2: Tìm l i g i hàm sai cho hàm sau: void func(int i=0,int j=0); a)func() b)dunc(1); Trang 9
  10. LP TRÌNH H NG I T NG V I C++ c)func(1.5,2.5); d)func(1,2); Câu 3: Cho bi t giá tr c a y sau khi th c hi n: int &foo(int &a) { a++; return a; } int i=5; int &r=foo(i); r++; a) i=5; b) i=6; c) i=7; d) không câu nào úng Câu 4: Tìm giá tr c a x, y: void test(int &a, int b) { a+=b; b=a; } int x=1,y=2; test(x,y); a) x=1,y=2; b) x=1,y=3 c) x=3,y=2 d) x=3,y=3 Bài t ập t ự gi ải Bài 1.1: Anh (ch ) hãy vi t l i ch ươ ng trình sau b ng cách s d ng l i các dòng nh p/xu t trong C++. /* Ch ươ ng trình tìm m u chung nh nh t */ #include void main() { int a,b,i,min; printf("Nhap vao hai so:"); scanf("%d%d",&a,&b); min=a>b?b:a; Trang 10
  11. LP TRÌNH H NG I T NG V I C++ for(i = 2;i<min;++i) if (((a%i)==0)&&((b%i)==0)) break; if(i==min) { printf("Khong co mau chung nho nhat"); } printf("Mau chung nho nhat la %d\n",i); } Bài 1.2: Vi t ch ươ ng trình nh p vào s nguyên d ươ ng h (2<h<23), sau ó in ra các tam giác có chi u cao là h nh ư các hình sau: Bài 1.3: M t tam giác vuông có th có t t c các c nh là các s nguyên. T p c a ba s nguyên c a các c nh c a m t tam giác vuông ưc g i là b ba Pitago. ó là t ng bình ph ươ ng c a hai c nh b ng bình ph ươ ng c a c nh huy n, ch ng h n b ba Pitago (3, 4, 5). Vi t ch ươ ng trình tìm t t c các b ba Pitago nh ư th sao cho t t c các c nh không quá 500. Bài 1.4: Vi t ch ươ ng trình in b ng c a các s t 1 n 256 d ưi d ng nh phân, bát phân và th p l c phân t ươ ng ng. Bài 1.5: Vi t ch ươ ng trình nh p vào m t s nguyên d ươ ng n. Ki m tra xem s nguyên n có thu c dãy Fibonacci không? Bài 1.6: Vi t ch ươ ng trình nhân hai ma trân Amxn và Bnxp. M i ma tr n ưc c p phát ng và các giá tr c a chúng phát sinh ng u nhiên (V i m, n và p nh p t bàn phím). Trang 11
  12. LP TRÌNH H NG I T NG V I C++ Bài 1.7: Vi t ch ươ ng trình t o m t m ng m t chi u ng có kích th ưc là n (n nh p t bàn phím). Các giá tr c a m ng này ưc phát sinh ng u nhiên trên on [a, b] v i a và b u nh p t bàn phím. Hãy tìm s d ươ ng nh nh t và s âm l n nh t trong m ng; nu không có s d ươ ng nh nh t ho c s âm l n nh t thì xu t thông báo "không có s dươ ng nh nh t" ho c "không có s âm l n nh t". Bài 1.8: Anh (ch ) hãy vi t m t hàm tính bình ph ươ ng c a m t s . Hàm s tr v giá tr bình ph ươ ng c a tham s và có ki u cùng ki u v i tham s . Bài 1.9: Trong ngôn ng C, chúng ta có hàm chuy n i m t chu i sang s , tùy thu c vào d ng c a chu i chúng ta có các hàm chuy n i sau : int atoi(const char *s); Chuy n i m t chu i s thành s nguyên ki u int. long atol(const char *s); Chuy n i m t chu i s thành s nguyên ki u long. double atof(const char *s); Chuy n i m t chu i s thành s th c ki u double. Anh (ch ) hãy vi t m t hàm có tên là aton (ascii to number) chuy n i chu i sang các d ng s t ươ ng ng. Bài 1.10: Anh ch hãy vi t các hàm sau: Hàm ComputeCircle() tính di n tích s và chu vi c c a m t ưng tròn bán kính r. Hàm này có prototype nh ư sau: void ComputeCircle(float & s, float &c, float r = 1.0); Hàm ComputeRectangle() tính di n tích s và chu vi p c a m t hình ch nh t có chi u cao h và chi u r ng w. Hàm này có prototype nh ư sau: void ComputeRectangle(float & s, float &p, float h = 1.0, float w = 1.0); Hàm ComputeTriangle() tính di n tích s và chu vi p c a m t tam giác có ba c nh a,b và c. Hàm này có prototype nh ư sau: void ComputeTriangle(float & s, float &p, float a = 1.0, float b = 1.0, float c = 1.0); Hàm ComputeSphere() tính th tích v và di n tích b m t s c a m t hình c u có bán kính r. Hàm này có prototype nh ư sau: void ComputeSphere(float & v, float &s, float r = 1.0); Trang 12
  13. LP TRÌNH H NG I T NG V I C++ Hàm ComputeCylinder() tính th tích v và di n tích b m t s c a m t hình tr có bán kính r và chi u cao h. Hàm này có prototype nh ư sau: void ComputeCylinder(float & v, float &s, float r = 1.0 , float h = 1.0); Bài 1.11: Vi t ch ươ ng trình qu n lý im h c sinh v i c u trúc danh sách n i ơn. Trong ch ươ ng trình s d ng toán t vào ra và toán t new c p phát b nh ng. Bài 1.12: Vi t m t hàm th c hi n vi c s p x p m t m ng s nguyên theo chi u t ng dn ho c gi m d n. Hàm này t ng m c nh ki u s p x p theo chi u t ng d n. Bài 1.13: Vi t m t hàm gi i ph ươ ng trình b c hai. Hàm này tr l i thông báo r ng ph ươ ng trình có nghi m hay không có nghi m kép. N u có nghi m thì nghi m s ưc lưu vào tham s x1, x2 và ưc truy n nh ư là tham bi n. Bài 1.14: Vi t m t hàm tìm v trí xu t hi n u tiên c a m t t khoá trong m t xâu. Hàm này tr l i v trí tìm th y c a t khoá trong xâu(b t u t 0) và thay i con tr xâu ưc truy n vào thành v trí c a ký t ngay sau ký t cu i cùng c a t khoá. T khoá cn tìm ưc ưa vào nh ư là m t tham s và có m t giá tr m c nh. Trang 13
  14. LP TRÌNH H NG I T NG V I C++ §èi t−îng vµ líp (Class and Object) MỤC TIÊU C ỦA BÀI NÀY GIÚP NG ƯỜI H ỌC  Phân tích ưc khái ni m óng gói d li u  Khai báo và s d ng m t l p  Khai báo và s d ng i t ưng.  S d ng hàm thi t l p và hàm hu b  Khai báo và s d ng hàm thi t l p sao chép  Vai trò c a hàm thi t l p ng m nh A/ NH ẮC L ẠI LÝ THUY ẾT Trong C++, tên c u trúc là m t ki u d li u không cn kèm theo t khoá struct. Lp cho phép ng ưi l p trình mô t các i t ưng th c t v i các thu c tính và hành vi. Trong C++ th ưng s d ng t khoá class khai báo m t l p. Tên l p là m t ki u d li u dùng khi khai báo các i t ưng th ưc l p(các th ể hi ện c ụ th ể c ủa l ớp) . Thu c tính c a i t ưng trong m t l p ưc mô t d ưi d ng các bi n th hi n. Các hành vi là các hàm thành ph n bên trong l p. Có hai cách nh ngh a các hàm thành ph n c a m t l p; khi nh ngh a hàm thành ph n bên ngoài khai báo l p ph i t tr ưc tên hàm thành ph n tên c a l p và toán t “::” phân bi t v i các hàm t do cùng tên. Ch nên nh ngh a hàm thành ph n bên trong khai báo l p khi nó không quá ph c t p cho ch ươ ng trình d c. Có th khai báo và s d ng các con tr i t ưng, tham chi u i t ưng. Hai t khoá public và private dùng ch nh thu c tính truy nh p cho các thành ph n( d li u/hàm) khai báo bên trong l p. Thành ph n bên trong l p ưc khai báo public có th truy nh p t m i hàm khai báo m t i t ưng thu c l p ó. Thành ph n private trong m t i t ưng ch có th truy nh p ưc b i các hàm thành ph n c a i t ưng ho c các hàm thành ph n c a l p dùng t o i t ưng( ây tính c tr ưng h p i t ưng là tham s c a hàm thành ph n) Hai hàm thành ph n c bi t c a m t l p gi là hàm thi t l p và hàm hu b . Hàm thi t l p ưc g i t ng(ng m nh) m i khi m t i t ưng ưc t o ra và hàm hu b ưc g i t ng khi i t ưng h t th i gian s d ng. Hàm thi t l p có thu c tính public, cùng tên v i tên l p nh ưng không có giá tr tr v. Mt l p có ít nh t hai hàm thi t l p: hàm thi t l p sao chép ng m nh và hàm thi t lp do ng ưi l p trình thi t l p(n u không mô t t ưng minh thì ó là hàm thi t l p ng m nh). Hàm hu b c ng có thu c tính public, không tham s , không giá tr tr v và có tên bt u b i ~ theo sau là tên c a l p. Bên trong ph m v l p( nh ngh a c a các hàm thành ph n), các thành ph n c a l p ưc g i theo tên. Tr ưng h p có m t i t ưng toàn c c cùng tên, mu n xác nh i tưng y ph i s d ng toán t “::”. Lp có th ch a các thành ph n d li u là các i t ưng c a l p khác. Các i tưng này ph i ưc kh i t o tr ưc i t ưng t ươ ng ng c a l p bao. Mi i t ưng có m t con tr ch n b n thân nó, ta g i ó là con tr this. Con tr này có th ưc s d ng t ưng minh ho c ng m nh tham xác nh các thành ph n bên trong i t ưng. Thông th ưng ng ưi ta s d ng this d ưi d ng ng m nh. Hàm b n c a m t l p là hàm không thu c l p nh ưng có quy n truy nh p t i các thành ph n private c a l p. Trang 14
  15. LP TRÌNH H NG I T NG V I C++ Khai báo b n b có th khai báo b t k ch nào trong khai báo l p. B. MỘT S Ố L ƯU Ý (Các l i th ưng g p, m t s thói quen l p trình t t )  Các l ỗi th ường g ặp  Quên d u “;” cu i khai báo l p  Kh i t o các thành ph n giá tr trong khai báo l p  nh ngh a ch ng m t hàm thành ph n b ng m t hàm không thu c l p  Truy nh p n các thành ph n riêng c a l p t bên ngoài ph m vi l p  Khai báo giá tr tr v cho hàm thi t l p và hàm hu b  Khai báo hàm hu b có tham s , nh ngh a ch ng hàm hu b  Gi t ưng minh hàm thi t l p và hàm hu b  Gi các thàm thành ph n bên trong hàm thi t l p  M ột s ố thói quen l ập trình t ốt  Nhóm t t c c các thành ph n có cùng thu c tính truy nh p m t n ơi tr ươ ng khái báo l p, nh v y m i t khoá mô t truy nh p ch ưc xác nh m t l n. Khai báo lp vì v y d c h ơn. Theo kinh nghi m, các thành ph n private tr ưc tiên r i n các thành ph n protectech, cu i cùng là t khoá public .  nh ngh a t t c các hàm thành ph n bên ngoài khai báo l p. iu này nh m ph n bi t gi a hai ph n giao di n và ph n cài t l p.  S d ng các ti n x lý #ifndef, #define, #endif cho các t p tin tiêu ch xu t hi n m t l n bên trong ch ươ ng trinhg ngu n.  Ph i nh ngh a các hàm thi t l p m b o r ng các i t ưng u ưc kh i to n i dung m t cách úng n. C/ BÀI T ẬP M ẪU Ví d  1: nh ngh a m t l p mô t và x lý các im trên màn hình ho . V i tên l p là point Lời gi ải + Các thu c tính c a l p int x;// hoành (c t) int y;// tung ( hàng) int m;// màu + Các ph ươ ng th c Nh p d li u m t im Hi n th m t im n m t im Lp im ưc xây d ng nh ư sau: class point { private : int x,y,m; public: void nhapsl(); void hien(); void an() { putpixcel(x,y,getbkcolor()); } void point::nhap() { cout >x>>y; cout >m; } void point::hien() Trang 15
  16. LP TRÌNH H NG I T NG V I C++ { int mau_ht; mau_ht=getcolor(); putpixcel(x,y,m); setcolor(mau_ht); } Nh n xét: + Trong c ba ph ươ ng th c( dù vi t trong hay vi t ngoài nh ngh a l p) u ưc truy nh p n các thu c tính x,y và m c a l p. + Các ph ươ ng th c vi t bên trong nh ngh a l p (nh ư ph ươ ng th c an()) ưc vi t nh ư m t hàm bình th ưng. +Khi xây d ng các ph ươ ng th c bên ngoài l p, c n dùng thêm tên l p và toán t ph m vi :: t ngay tr ưc tên ph ươ ng th c quy nh rõ ây là ph ươ ng th c c a l p nào. Ví d 2: Chúng ta xây d ng ki u c u trúc Time vi ba thành viên s nguyên: Hour , Minute và second . Ch ươ ng trình nh ngh a m t c u trúc Time g i là DinnerTime . Ch ươ ng trình in th i gian d ưi d ng gi quân i và d ng chu n. CT2_2.CPP #include class Time { public: Time(); //Constructor void SetTime(int, int, int); //Thiet lap Hour, Minute va Second void PrintMilitary(); //In thoi gian duoi dang gio quan doi void PrintStandard(); //In thoi gian duoi dang chuan private : int Hour; // 0 - 23 int Minute; // 0 - 59 int Second; // 0 - 59 }; //Constructor khoi tao moi thanh vien du lieu voi gia tri zero //Bao dam tat ca cac doi tuong bat dau o trang thai thich hop Time::Time() { Hour = Minute = Second = 0; } //Thiet lap mot gia tri Time moi su dung gio quan doi //Thuc hien viec kiem tra tinh hop le tren cac gia tri du lieu //Thiet lap ca gia tri khong hop le thanh zero void Time::SetTime(int H, int M, int S) { Hour = (H >= 0 && H = 0 && M = 0 && S < 60) ? S : 0; } //In thoi gian duoi dang gio quan doi void Time::PrintMilitary() { cout << (Hour < 10 ? "0" : "") << Hour << ":" Trang 16
  17. LP TRÌNH H NG I T NG V I C++ << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second; } //In thoi gian duoi dang chuan void Time::PrintStandard() { cout << ((Hour == 0 || Hour == 12) ? 12 : Hour % 12) << ":" << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second << (Hour < 12 ? " AM" : " PM"); } int main() { Time T; cout << "The initial military time is "; T.PrintMilitary(); cout << endl << "The initial standard time is "; T.PrintStandard(); T.SetTime(13, 27, 6); cout << endl << endl << "Military time after SetTime is "; T.PrintMilitary(); cout << endl << "Standard time after SetTime is "; T.PrintStandard(); T.SetTime(99, 99, 99); //Thu thiet lap gia tri khong hop le cout << endl << endl << "After attempting invalid settings:" << endl << "Military time: "; T.PrintMilitary(); cout << endl << "Standard time: "; T.PrintStandard(); cout << endl; return 0; } k t qu Trang 17
  18. LP TRÌNH H NG I T NG V I C++ Ví d  3 Nh p mt ngày tháng n m t bàn phím sau ó in ra màn hình. Lời gi ải CT2_3.CPP #include #include #define FALSE 0 #define TRUE !FALSE char* Thang[]={"","gieng","hai","ba","bon","nam","sau","bay","tam", "chin","muoi","muoi mot","chap"}; int NgayThang[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; class CDate { private : int mNgay,mThang,mNam; int laNamNhuan(int); public: void nhap(); int hopLe(); void in(); }; void CDate::nhap() { cout >mNgay; cout >mThang; cout >mNam; } int CDate::hopLe() { if ((mThang 12)) return FALSE; else { if ((mNgay>=1)&&(mNgay<=NgayThang[mThang])) return TRUE; else if ((mNgay==29)&&laNamNhuan(mNgay)) return TRUE; else return FALSE; } } int CDate::laNamNhuan(int nam) { if (((nam%400)==0)||(((nam%4)==0)&&((nam%100)!=0))) return TRUE; else return FALSE; } void CDate::in() { cout<<endl<<"Ban da nhap vao ngay "<<mNgay; cout<<" thang "<<Thang[mThang]; cout<<" nam "<<mNam; } void main() { CDate ngay; ngay.nhap(); if (ngay.hopLe()) ngay.in(); else Trang 18
  19. LP TRÌNH H NG I T NG V I C++ cout<<"BAN NHAP NGAY KHONG HOP LE"; getch(); } Ví d  4 Ch ra các cách khai báo i t ưng có th cho các l p i t ưng d ưi ây: class A { }; class B { B(int, int); public: B(int=0); }; class C { C(C&); public: C(); }; class D { public: D(D&); }; Lời gi ải V  l p A Cách 1: S d ng hàm thi t l p ng m nh A a; ho c A a(); Cách 2: S d ng hàm thi t l p sao chép m c nh. Gi s a là m t i t ưng c a lp A ã ưc khai báo tr ưc. Ta có th khai báo i t ưng a1 nh ư sau: A a1(a); ho c A a1=a; Nh ận xét: Khi trong l p không có m t khai báo hàm thi t l p nào thì trình biên d ch t ng to ra m t hàm thi t l p m c nh cho l p ó. Do v y ta có th s d ng khai báo i tưng theo cách 1 cho l p A. Hai chách vi t khai báo A a1(a); và A a1=a; là hoàn toàn gi ng nhau, chúng u s d ng hàm thi t l p sao chép kh i t o i t ưng. V l p B Cách 1: S d ng hàm thi t l p B(int). Ví d : B b(5); Cách 2: S d ng hàm thi t l p B(int) v i tham s ng m nh là 0. B b; t ươ ng ươ ng v i B b(0); Cách 3: S d ng hàm thi t l p sao chép t ươ ng t nh ư l p A. B b1=b; Nh ận xét Chúng ta ch có th khai báo i t ưng theo các hàm thi t l p có thu c tính quy n truy nh p là public Trang 19
  20. LP TRÌNH H NG I T NG V I C++ Trong hàm thi t l p c ng có th s d ng tham s ng m nh gi ng nh ư các hàm thành ph n khác. V l p C: Ch có th khai báo i t ưng theo hàm thi t l p C() b i vì hàm thi t l p sao chép ã ưc ng ưi s d ng nh ngh a và t quy n truy xu t là private . Do v y không th dùng hàm thi t l p sao chép. Ví d : C c; V l p D: Không th khai báo i t ưng cho l p D b i vì trong l p này ch có hàm thi t l p sao chép. Hàm thi t l p chép mu n s d ng ưc thì ph i có m t i t ưng c a l p D. Do vy mu n khai báo ưc m t i t ưng thu c l p D thì trong l p D c n có m t hàm thi t l p khác sa chép. Ví d  5 Có bao nhiêu l n hàm thi t l p sao chép ưc g i trong on mã ch ươ ng trình sau: Widget f(Widget u) { Widget v(u); Widget w=v; return w; } void main() { Widget x; Widget y=f(f(x)); } Lời giải: Hàm thi t l p sao chép ưc g i 7 l n trong on mã chươ ng trình này. M i l n g i hàm f òi h i 3 l n g i n hàm thi t l p sao chép: khi tham sô truy n vào b ng giá tr u, khi v và w ưc kh i t o. L nh g i th b y là kh i t o y. Ví d  6 Cho bi t k t qu in ra màn hình c a ch ươ ng trình sau: Lời gi ải CT 2_6.CPP #include #include 3. class A { static int count; public: A() { count++;} ~A() { count ;} static void printNum() { cout<<” Gia tri cua count la:”<<count<<endl; } }; int A::count=0; void main() { clrscr(); A::printNum(); A a1; a1.printNum(); A *pa=new A; a1.printNum(); Trang 20
  21. LP TRÌNH H NG I T NG V I C++ delete pa; a1.printNum(); A a2=a1; a2.printNum(); getch(); } 4. Lời gi ải Kt q in ra màn hình: Gia tri cua count la 0 Gia tri cua count la 1 Gia tri cua count la 2 Gia tri cua count la 1 Gia tri cua count la 1 Trong l p A, thu c tính count và hàm thành ph n printNum là các thành ph n t nh ưc chia s b i m i i t ưng c a A. Ban u thu c tính count ưc khai báo kh i to là 0( dòng int A::count=0), do v y dòng u tiên ca ch ươ ng trình chính ưc g i n ph ươ ng th c printNum s ưa ra màn hình giá tr c a count là 0. Ti p theo ta t o mt i t ưng a1 s d ng hàm thi t l p d ng A(). Hàm này làm t ng count lên 1. Do vy, dòng g i ph ươ ng th c printNum ti p theo s ưa ra màn hình giá tr c a count là 1. T ươ ng t i v i l nh new ta c ng t o ra m t i t ưng m i và lúc này giá tr c a count là 2. Sau khi s d ng l nh new t o i t ưng, ch ươ ng trình s d ng delete xoá i t ưng ó kh i b nh . Lúc này hàm hu b ưc g i và count gi m xu ng 1. i t ưng a2 ưc khai báo s d ng hàm thi t l p sao chép m c nh, mà hàm này không làm thay i giá tr count. Do v y, count v n gi giá tr 1. Ví d  6 Tim ra ch sai v quy n truy xu t trong on ch ươ ng trình sau: class A { int pri; public: int bub; friend void funcA(A); firend class B; }; class B { void func(A a) { cout<<a.pri; cout<<a.pub; } }; class C { void func(A a) { cout<<a.pri; cout<<a.pub; Trang 21
  22. LP TRÌNH H NG I T NG V I C++ } }; void funcA(A a) { cout #include 5. #include class ThiSinh { // Các thu c tính char ten[25];// Tên c a thí sinh khôngdài quá 24 ký t int toan, ly, hoa;// im ba môn toán, lý, hoá public: // Các ph ươ ng th c void nhapdl();//Nh p d li u cho thí sinh void inkq();// In k t qu thi c a thí sinh int tong();// Tính t ng im c a thí sinh }; void ThiSinh::nhapdl() { cout >toan; cout >ly; cout >hoa; } Trang 22
  23. LP TRÌNH H NG I T NG V I C++ void ThiSinh::inkq() { // K t qu thi c a thí sinh ưc in trên m t dòng theo nh d ng // Ten Toan Ly Hoa Tong printf(“%-25s%6d%6d%6%6d\n”,ten,toan,ly,hoa,tong()); } int ThiSinh::tong() { return (toan+ly+hoa); } void main() { // Ch ươ ng trình chính th c hi n nh p danh sách vào s l ưng thí // sinh c n nh p clrscr(); int n; cout >n; // T o n i t ưng thí sinh cho n thí sinh c n nh p d li u ThiSinh *dsts=new ThiSinh[n]; // Nh p d li u cho t ng thí sinh for(int i=0;i =18) dsts[i].inkq(); // Xoá các i t ưng ã t o và k t thúc ch ươ ng trình delete dsts; getch(); } 6. Ví d  8: Hàm thi t l p v i các tham s m c nh CT2_8.CPP #include class Time 7. { public: Time(int = 0, int = 0, int = 0); //Constructor mac dinh void SetTime(int, int, int); void PrintMilitary(); void PrintStandard(); private : int Hour; int Minute; int Second; }; //Ham constructor de khoi dong du lieu private //Cac gia tri mac dinh la 0 Time::Time(int Hr, int Min, int Sec) { Trang 23
  24. LP TRÌNH H NG I T NG V I C++ SetTime(Hr, Min, Sec); } //Thiet lap cac gia tri cua Hour, Minute va Second //Gia tri khong hop le duoc thiet lap la 0 void Time::SetTime(int H, int M, int S) { Hour = (H >= 0 && H = 0 && M = 0 && S < 60) ? S : 0; } //Hien thi thoi gian theo dang gio quan doi: HH:MM:SS void Time::PrintMilitary() { cout << (Hour < 10 ? "0" : "") << Hour << ":" << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second; } //Hien thi thoi gian theo dang chuan: HH:MM:SS AM (hoac PM) void Time::PrintStandard() { cout << ((Hour == 0 || Hour == 12) ? 12 : Hour % 12) << ":" << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second << (Hour < 12 ? " AM" : " PM"); } int main() { Time T1,T2(2),T3(21,34),T4(12,25,42),T5(27,74,99); cout << "Constructed with:" << endl << "all arguments defaulted:" << endl << " "; T1.PrintMilitary(); cout << endl << " "; T1.PrintStandard(); cout << endl << "Hour specified; Minute and Second defaulted:" << endl << " "; T2.PrintMilitary(); cout << endl << " "; T2.PrintStandard(); cout << endl << "Hour and Minute specified; Second defaulted:" << endl << " "; T3.PrintMilitary(); cout << endl << " "; T3.PrintStandard(); cout << endl << "Hour, Minute, and Second specified:" << endl << " "; T4.PrintMilitary(); cout << endl << " "; T4.PrintStandard(); cout << endl << "all invalid values specified:" << endl << " "; T5.PrintMilitary(); cout << endl << " "; T5.PrintStandard(); cout << endl; return 0; } 8. Trang 24
  25. LP TRÌNH H NG I T NG V I C++ Ch ươ ng trình ví d trên kh i t o n m i t ưng c a l p Time ( dòng 52). i tưng T1 vi ba tham s l y giá tr m c nh, i t ưng T2 vi m t tham s ưc mô t, i t ưng T3 vi hai tham s ưc mô t , i t ưng T4 vi ba tham s ưc mô t và i t ưng T5 vi các tham s có giá tr không h p l . Kt qu Ví d  9: Lp có hàm hu b CT 2_9.CPP #include class Simple 9. { private : int *X; public: Simple(); //Constructor ~Simple(); //Destructor void SetValue(int V); int GetValue(); }; Simple::Simple() { X = new int; //Cap phat vung nho cho X } Simple::~Simple() { delete X; //Giai phong vung nho khi doi tuong bi huy bo } Trang 25
  26. LP TRÌNH H NG I T NG V I C++ void Simple::SetValue(int V) { *X = V; } int Simple::GetValue() { return *X; } int main() { Simple S; int X; cout >X; S.SetValue(X); cout class Count { friend void SetX(Count &, int); //Khai bao friend public: Count()//Constructor { X = 0; } void Print() const //Xuat { cout << X << endl; } private : int X; }; //Co the thay doi du lieu private cua lop Count vi //SetX() khai bao la mot ham friend cua lop Count void SetX(Count &C, int Val) { Trang 26
  27. LP TRÌNH H NG I T NG V I C++ C.X = Val; //Hop le: SetX() la mot friend cua lop Count } int main() { Count Object; cout << "Object.X after instantiation: "; Object.Print(); cout << "Object.X after call to SetX friend function: "; SetX(Object, 8); //Thiet lap X voi mot friend Object.Print(); return 0; } kt qu D/ BÀI T ẬP T Ự GI ẢI Câu h ỏi tr ắc nghi ệm Câu 1: Ch có m t kh ng nh trong nh ng câu sau là sai. Câu nào? a./ M i th hi n c a m t l p có s h u riêng các thu c tính thông th ưng b./ Các th hi n c a m t l p cùng chia s các thu c tính t nh c a l p ó c./ M i th hi n c a m t l p có các nh ngh a riêng cho các ph ươ ng th c c a nó. d./ M i i t ưng là m t th hi n c a m t l p Câu 2: Các t khoá public và private dùng a./ Cho phép ng ưi thi t k l p che d u m t ph n thi hành c a l p tr ưc ng ưi s dng l p. b./ Trình biên d ch t i ưu hoá ch ươ ng trình c./ m b o na toàn c a l p khi thi t k d./ H n ch vi c sao chép l p Câu 3 Ch ra l i sai v i các khai báo cho l p A class A { A(int i); }; A a1;//(1) A b2(5) //(2) a./ Ch dòng 1 l i b./ Ch dòng 2 l i c./ C hai dòng l i d./ Không dòng nào l i Câu 4: Cho bi t giá tr c a n v i các dòng l nh sau: Trang 27
  28. LP TRÌNH H NG I T NG V I C++ class A { public: static int i; }; int A::i=5; A a1; a1.i++; A a2; int n=a2.i+1; a./ n=5; b./ n=6; c./ n=7; d./ Không câu nào úng Câu 5: Ch ra l i v i các khai báo cho l p A class A { public: A(int i); }; A a1(5); A a3;// (1) A a2=a1;// (2) a./ Ch dòng 1 l i b./ Ch dòng 2 l i c./ C 2 dòng l i d./ Không dòng nào l i Bài tâp Bài 2.1: Xây d ng l p Stack, d li u bao g m nh stack và vùng nh c a stack. Các thao tác g m: Kh i ng stack. Ki m tra stack có r ng không? Ki m tra stack có y không? Push và pop. Bài 2.2: Xây d ng l p hình tr Cylinder, d li u bao g m bán kính và chi u cao c a hình tr . Các thao tác g m hàm tính di n tích toàn ph n và th tích c a hình tr ó. Bài 2.3: Hãy xây d ng m t l p Point cho các im trong không gian ba chi u (x,y,z). Lp ch a m t constructor m c nh, m t hàm Negate() bi n i im thành i lưng có d u âm, m t hàm Norm() tr v kho ng cách t g c và m t hàm Print(). Bài 2.4: Xây d ng m t l p Matrix cho các ma tr n bao g m m t constructor m c nh, hàm xu t ma tr n, nh p ma tr n t bàn phím, c ng hai ma tr n, tr hai ma tr n và nhân hai ma tr n. Trang 28
  29. LP TRÌNH H NG I T NG V I C++ Bài 2.5: Xây d ng m t l p Matrix cho các ma tr n vuông bao g m m t constructor m c nh, hàm xu t ma tr n, tính nh th c và tính ma tr n ngh ch o. Bài 2.6: Xây d ng l p Person qu n lý h tên, n m sinh, im chín môn h c c a t t c các h c viên c a l p h c. Cho bi t bao nhiêu h c viên trong l p ưc phép làm lu n vn t t nghi p, bao nhiêu h c viên thi t t nghi p, bao nhiêu ng ưi ph i thi l i và tên môn thi l i. Tiêu chu n xét: Làm lu n v n ph i có im trung bình l n h ơn 7 trong ó không có môn nào d ưi 5. Thi t t nghi p khi im trung bình không l n h ơn 7 và im các môn không d ưi 5. Thi l i có môn d ưi 5. Bài 2.7: Xây d ng m t l p String. M i i t ưng c a l p String s i di n m t chu i ký t. Các thành viên d li u là chi u dài chu i và chu i ký t th c. Ngoài constructor và destructor còn có các ph ươ ng th c nh ư t o m t chu i v i chi u dài cho tr ưc, t o m t chu i t m t chu i ã có. Bài 2.8: Xây d ng m t l p Vector l ưu tr vector g m các s th c. Các thành viên d li u g m: Kích th ưc vector. Mt m ng ng ch a các thành ph n c a vector. Ngoài constructor và destructor, còn có các ph ươ ng th c tính tích vô h ưng c a hai vector, tính chu n c a vector (theo chu n b t k nào ó). Bài 2.9: Xây d ng l p Employee g m h tên và ch ng minh nhân dân. Ngoài constructor còn có ph ươ ng th c nh p, xu t h tên và ch ng minh nhân dân ra màn hình Bài 2.10: Mt l p i t ưng sách trong h th ng qu n lí th ư vi n có các thu c tính - Tên sách - Tng s quy n sách - S quy n sách ã cho m ưn Xây d ng l p i t ưng trên v i các ph ươ ng th nh ư sau - Ph ươ ng th nh p d li u cho i t ưng t bàn phím. Các thông tin c n nh p là tên sách, t ng s sách, s ã cho m ưn. - Ph ươ ng th c in thông tin i t ưng ra màn hình bao g m tên, t ng s và s ã cho m ưn. - Ph ươ ng th c tính s sách còn l i trong th ư vi n(t ng s - s m ưn) Trên c ơ s l p xây d ng ưc, vi t ch ươ ng trình chính th c hi n các công vi c. - Nh p danh sách các quy n sách v i s l ưng sách c n nh p ưc cho vào t bàn phím. - ư a ra màn hình thông tin v các quy n sách hi n có trong th ư vi n(s sách còn li ph i l n h ơn 0) Trang 29
  30. LP TRÌNH H NG I T NG V I C++ Bài 2.11: Vi t m t l p bi u di n hình ch nh t có các thu c tính là dài hai c nh( chi u r ng và chi u dài) và có các ph ươ ng th c sau. - Nh p d li u hai c nh cho hình ch nh t - Tính chu vi và di n tích hình ch nh t - In thông tin c a hình ch nh t ra màn hình(bao g m dài hai c nh, chu vi và di n tích) Trên c ơ s l p xây d ng ưc vi t ch ươ ng trình cho phép ng ưi s d ng nh p d li u c a m t hình ch nh t r i in thông tin v nó ra màn hình. Bài 2.12: Xây d ng m t l p Date mô t thông tin v ngày, tháng, n m(month, day, year). L p Date có các hàm thành ph n: - Hàm thi t l p v i ba tham s có giá tr m c nh(ó là ngày h th ng) - Nh p d li u ngày, tháng và n m - Hàm in thông tin v ngày tháng n m d ưi d ng mm-dd-yy - Hàm nextDay() t ng Date t ng ngày m t Trên c ơ s l p Date v a x y d ng vi t ch ươ ng trình cho bi t kho ng cách ngày gi a hai m c th i gian vi ngày b t u ưc nh p vào t bàn phím cho t ơi ngày hi n th i. Bài 2.13: Xây d ng l p Stack và l p Queue mô t ho t ng c a ng n x p và hàng i các sô nguyên. Bài 2.14: Xây d ng m t l p mô t các b ng thi u bóng á gi là BangThiDau. Gi thi t m i bng có b n i và thi u chéo t ng c p. Có l ch các tr n u c a b ng. T o các ph ươ ng th c nh p k t qu thi u và tính im cho t ng i. Yêu c u vi c nh p k t qa thi u ph i theo th t th i gian. Thêm các ph ươ ng th c hi n th thông tin thi u ca t ng i và c a c b ng. Vi t ch ươ ng trình ki m nghi m l p xây d ng ưc. Bài 2.15: M r ng bài t p trên v i l p DoiBong mô t các i bóng thi u. Thông tin c a m i ôi bóng bao g m tên i bóng, danh sách c u th , và hu n luy n viên. L p bangThiDau s d ng các i t ưng c a l p DoiBong làm i bóng thi u c a b ng. Các b ng lúc này có th m thu c tính tên c a b ng thi u. S d ng các l p ã xây d ng trên vi t ch ươ ng trình qu n lý thi u c a cúp bóng á th gi i có 32 i thi u ưc chia làm 8 b ng. T o thêm l p mô t l ch thi u cho các vòng ti p theo c a gi i. Yêu c u c a ch ươ ng trình nh ư sau: - Ban u ng ưi s d ng nh p các thông tin v i bóng, sau ó phân b ng và l ch thi u toàn gi i. - Kt qu các tr n thi u ưc vào theo th t l ch thi u - Ch ươ ng trình t ng ch n các i vào vòng ti p theo cho t i tr n trung k t. - Ti m i th i im c a gi i ch ươ ng trình có th ưa ra các thông tin v gi i. Bài 2.16: Mt quy n s in tho i ch a các th có thông tin v tên, a ch và s in tho i. Thi t k các l p t ươ ng ng v i các th thông tin và s in tho i. Vi t ch ươ ng trình cho phép qu n lý s in tho i d a trên các l p xây d ng ưc. Trang 30
  31. LP TRÌNH H NG I T NG V I C++ §Þnh nghÜa chång to¸n tö trªn líp MỤC TIÊU C ỦA BÀI NÀY GIÚP NG ƯỜI H ỌC  Cách nh ngh a các phép toán cho ki u d li u l p và c u trúc  Các toán t chuy n ki u áp d ng cho ki u d li u l p A/ NH ẮC L ẠI LÝ THUY ẾT Toán t ưc nh ngh a ch ng b ng cách nh ngh a m t hàm toán t . Tên hàm toán t bao g m t khoá operator theo sau là ký hi u c a toán t ưc nh ngh a ch ng. Hu h t các toán t c a C++ u có th nh ngh a ch ng. Không th t o ra các ký hi u phép toán m i. Ph i m b o các c tính nguyên thu c a toán t ưc nh ngh a ch ng, ch ng hn: ưu tiên, tr t t k t h p, sô ngôi. Không s d ng tham s có giá tr ng m nh nh ngha ch ng toán t . Các toán t (), [], ->, = yêu c u hàm toán t ph i là hàm thành ph n c a l p. Hàm toán t có th là hàm thành ph n hay là hàm b n c a l p Khi hàm toán t là hàm thành ph n, toán h ng bên trái luôn là i thu c l p. Nu toán h ng bên trái là i t ưng c a l p khác thì hàm toán t t ươ ng ng ph i là hàm b n. Ch ươ ng trình d ch không t bi t cách chuy n ki u gi a ki u d li u chu n và ki u d li u t nh ngh a. Vì v y ng ưi l p trình c n ph i mô t t ưng minh các chuy n i này d ưi d ng hàm thi t l p chuy n ki u hay hàm toán t chuy n ki u. Mt hàm toán t chuy n ki u th c hi n chuy n i t m t i t ưng th ưc l p sang i t ưng thu c l p khác ho c m t i t ưng có ki u ưc nh ngh a tr ưc. Hàm thi t l p chuy n ki u có m t tham s và th c hi n chuy n i t m t giá tr sang i t ưng ki u l p. Toán t gán là toán t hay ưc nh nhgiã ch ng nh t, c bi t khi l p có các thành ph n d li u ng. nh ngh a ch ng toán t t ng, gi m m t ngôi, ph i phân bi t hai hàm toán t tưng ng cho d ng ti n t và d ng h u t . B. MỘT S Ố L ƯU Ý (Các l i th ưng g p, m t s thói quen l p trình t t )  Các l ỗi th ường g ặp  To m t toán t  Thay i nh ngh a c a các toán t trên các ki u ưc nh ngh a tr ưc  Cho r ng vi c nh ngh a ch ng m t toán t s t ng kéo theo nh ngh a ch ng ca các toán t liên quan.  Quên nh ngh a ch ng toán t gán và hàm thi t l p sao chép cho các l p có các thành ph n d li u ng.  M ột s ố thói quen l ập trình t ốt  S d ng toán t nh ngh a ch ng khi iu ó làm cho ch ươ ng trình trong sáng hơn.  Tránh l m d ng nh ngh a ch ng toán t vì iu ó ãn n khó ki m soát ch ươ ng trình.  Chú ý n các tính ch t nguyên thu c a toán t ưc nh ngh a ch ng.  Hàm thi t l p, toán t gán, hàm thi t l p sao chép c a m t l p thưng i cùng nhau. Trang 31
  32. LP TRÌNH H NG I T NG V I C++ C/ BÀI T ẬP M ẪU Ví d  1: Mt l p phân s có toán t c ng(+) ưc nh ngh a nh ư sau: class PS { public: PS(int ts=0, int ms=1); PS operator+(PS); }; Trong các dòng l nh sau ây dòng nào sai? PS a,b,c; a=b+c;//(1) a=b+3;//(2) a=3+b;//(3) Lời gi ải Trong ba dòng l nh thì hai dòng u là úng b i vì lúc ó ta có: (1) a=b.operator+(c) là toán t ã ưc nh ngh a trong l p phân s (2)  a=b.operator+(3) v i 3 s t ng chuy n ki u thành phân s Dòng l nh (3) sai vì ta không có toán t c ng m t s nguyên v i m t phân s . có th th c hi n ưc t t c ba dòng l nh nh ư trên thì toán t c ng trong l p PS ph i ưc nh ngh a là m t hàm b n. class PS { public: PS(int ts=0, int ms=1); friend PS operator+(PS); }; Khi ó các l i gi s t ươ ng ng v i toán t nh ư sau: (1) a=operator+(b,c) (2) a=operator+(b,3) (3) a=operator+(3,b) Ví d  2:Chúng ta xây d ng l p s ph c v i tên l p là Complex và a n ng hóa toán t + trên l p này. CT3_1.CPP #include class Complex 11. { private : double Real,Imaginary; public: Complex(double R=0.0,double I=0.0);//Constructor mac dinh void Print();//Hien thi so phuc Complex operator + (Complex Z);//Phep cong hai so phuc Complex operator + (double R);//Phep cong mot so phuc voi mot so thuc }; Complex::Complex(double R,double I) { Real = R; Imaginary = I; } Trang 32
  33. LP TRÌNH H NG I T NG V I C++ void Complex::Print() { cout<<'('<<Real<<','<<Imaginary<<')'; } Complex Complex::operator + (Complex Z) { Complex Tmp; Tmp.Real = Real + Z.Real; Tmp.Imaginary = Imaginary + Z.Imaginary; return Tmp; } Complex Complex::operator + (double R) { Complex Tmp; Tmp.Real = Real + R; Tmp.Imaginary = Imaginary; return Tmp; } int main() { Complex X,Y(4.3,8.2),Z(3.3,1.1); cout<<"X: "; X.Print(); cout<<endl<<"Y: "; Y.Print(); cout<<endl<<"Z: "; Z.Print(); X = Y + Z; cout<<endl<<endl<<"X = Y + Z:"<<endl; X.Print(); cout<<" = "; Y.Print(); cout<<" + "; Z.Print(); X = Y + 3.5; cout<<endl<<endl<<"X = Y + 3.5:"<<endl; X.Print(); cout<<" = "; Y.Print(); cout<<" + 3.5"; return 0; } 12. kt qu Trang 33
  34. LP TRÌNH H NG I T NG V I C++ Ví d  3: Cho m t l p có toán t chuy n ki u nh ư sau: class A { public: operator int (); }; Khi ó ta có th s d ng câu l nh nào trong nh ng câu l n sau: A a; int i=a;//(1) float f=a;//(2) Lời gi ải Lnh (1) là úng b i vì ta ã có toán t ép ki u int nên ch ươ ng trình t ng ép ki u v m t s nguyên. Còn l nh 2 sai b i vì ta không có toán t ép ki u float. Ví d  4 a n ng hóa toán t [] truy c p n m t ph n t c a vector. CT3_4.CPP #include class Vector 13. { private : int Size; int *Data; public: Vector(int S=2,int V=0); ~Vector(); void Print() const; int & operator [] (int I); }; Vector::Vector(int S,int V) { Size = S; Data=new int[Size]; for(int I=0;I<Size;++I) Data[I]=V; } Vector::~Vector() { delete []Data; } void Vector::Print() const { cout<<"Vector:("; Trang 34
  35. LP TRÌNH H NG I T NG V I C++ for(int I=0;I 15. class Vector { private : int Size; int *Data; public: Vector(int S=2,int V=0); ~Vector(); void Print() const; int & operator () (int I); }; Vector::Vector(int S,int V) { Size = S; Data=new int[Size]; for(int I=0;I<Size;++I) Data[I]=V; } Vector::~Vector() { Trang 35
  36. LP TRÌNH H NG I T NG V I C++ delete []Data; } void Vector::Print() const { cout 17. class Matrix { private : int Rows,Cols; int Data; public: Matrix(int R=2,int C=2,int V=0); ~Matrix(); void Print() const; int & operator () (int R,int C); }; Matrix::Matrix(int R,int C,int V) { int I,J; Rows=R; Cols=C; Trang 36
  37. LP TRÌNH H NG I T NG V I C++ Data = new int *[Rows]; int *Temp=new int[Rows*Cols]; for(I=0;I<Rows;++I) { Data[I]=Temp; Temp+=Cols; } for(I=0;I<Rows;++I) for(J=0;J<Cols;++J) Data[I][J]=V; } Matrix::~Matrix() { delete [] Data[0]; delete [] Data; } void Matrix::Print() const { int I,J; for(I=0;I<Rows;++I) { for(J=0;J<Cols;++J) { cout.width(5);//Hien thi canh ler phai voi chieu dai 5 ky tu cout<<Data[I][J]; } cout<<endl; } } int & Matrix::operator () (int R,int C) { return Data[R][C]; } int main() { int I,J; Matrix M(2,3,1); cout<<"Matrix:"<<endl; M.Print(); for(I=0;I<2;++I) for(J=0;J<3;++J) M(I,J)*=(I+J+1); cout<<"Matrix:"<<endl; M.Print(); return 0; } 18. kt qu Trang 37
  38. LP TRÌNH H NG I T NG V I C++ Ví d ụ 7: a n ng hóa toán t ++ và CT3_7.CPP #include 19. class Point { private : int X,Y; public: Point(int A=0,int B=0); Point operator ++(); Point operator (); void Print() const; }; Point::Point(int A,int B) { X = A; Y = B; } Point Point::operator++() { ++X; ++Y; return *this; } Point Point::operator () { X; Y; return *this; } void Point::Print() const { cout<<"X="<<X<<",Y="<<Y<<endl; } int main() { Point P1(2,6),P2(5,8); cout<<"Point 1:"; P1.Print(); cout<<"Point 2:"; P2.Print(); ++P1; P2; cout<<"Point 1:"; P1.Print(); Trang 38
  39. LP TRÌNH H NG I T NG V I C++ cout 21. class Point { private : int X,Y; public: Point(int A=0,int B=0); Point operator +(Point P); Point operator ,(Point P); void Print() const; }; Point::Point(int A,int B) { X = A; Y = B; } Point Point::operator+(Point P) { Point Tmp; Tmp.X=X+P.X; Tmp.Y=Y+P.Y; return Tmp; } Point Point::operator,(Point P) { Point Tmp; Tmp.X=P.X; Tmp.Y=P.Y; cout<<P.X<<" "<<P.Y<<endl; return Tmp; } void Point::Print() const { cout<<"X="<<X<<",Y="<<Y<<endl; } Trang 39
  40. LP TRÌNH H NG I T NG V I C++ int main() { Point P1(2,6),P2(5,20),P3(1,1); cout . CT3_9.CPP #include 23. class My Class { public: int Data; My Class * operator ->() { return this; } }; int main() { My Class M; M->Data = 10; cout Data; return 0; } 24. kt qu Ví d  10: a n ng hóa toán t gán. CT3_10.CPP Trang 40
  41. LP TRÌNH H NG I T NG V I C++ #include #include 25. class String { private : char *St; int Len; public: String(char *S); ~String(); char *GetStr(); String & operator=(String &Obj); }; String::String(char *S) { Len=strlen(S); St=new char[Len+1]; strcpy(St,S); } String::~String() { delete []St; } char * String::GetStr() { return St; } String & String::operator=(String &Obj) { if (Len< Obj.Len) { delete [] St; St=new char[Obj.Len+1]; } Len=Obj.Len; strcpy(St,Obj.St); return *this; } int main() { String S1("Hello"), S2("Chao"); cout<<"S1="<<S1.GetStr()<<endl; cout<<"S2="<<S2.GetStr()<<endl; S2=S1; cout<<"S1="<<S1.GetStr()<<endl; cout<<"S2="<<S2.GetStr()<<endl; return 0; } 26. kt qu Trang 41
  42. LP TRÌNH H NG I T NG V I C++ Ví d  11: Chúng ta s xây d ng m t l p x lý vi c t o và thao tác trên các chu i (string). C++ không cài s n ki u d li u chu i. Nh ưng C++ cho phép chúng ta thêm ki u chu i nh ư m t l p thông qua c ơ ch a n ng hóa. CT3_11.CPP #include #include 27. #include #include class String { private : char *Ptr; //Con tro tro den diem bat dau cua chuoi int Length; //Chieu dai chuoi public: String(const char * = ""); //Constructor chuyen doi String(const String &); //Constructor sao chep ~String(); //Destructor const String &operator=(const String &); //Phep gan String &operator+=(const String &); int operator!() const; int operator==(const String &) const; int operator!=(const String &) const; int operator (const String &) const; int operator>=(const String &) const; int operator >(istream &, String &); }; //Constructor sao chep: Chuyen doi char * thanh String String::String(const char *S) { cout << "Conversion constructor: " << S << endl; Length = strlen(S); Ptr = new char[Length + 1]; assert(Ptr != 0); strcpy(Ptr, S); } String::String(const String &Copy) { cout << "Copy constructor: " << Copy.Ptr << endl; Trang 42
  43. LP TRÌNH H NG I T NG V I C++ Length = Copy.Length; Ptr = new char[Length + 1]; assert(Ptr != 0); strcpy(Ptr, Copy.Ptr); } //Destructor String::~String() { cout (const String &Right) const Trang 43
  44. LP TRÌNH H NG I T NG V I C++ { return strcmp(Ptr, Right.Ptr) > 0; } int String::operator>=(const String &Right) const { return strcmp(Ptr, Right.Ptr) >= 0; } int String::operator = 0 && Subscript = 0 && Index = 0); String *SubPtr = new String; assert(SubPtr != 0); if ((SubLength == 0) || (Index + SubLength > Length)) SubPtr->Length = Length - Index + 1; else SubPtr->Length = SubLength + 1; delete SubPtr->Ptr; SubPtr->Ptr = new char[SubPtr->Length]; assert(SubPtr->Ptr != 0); strncpy(SubPtr->Ptr, &Ptr[Index], SubPtr->Length); SubPtr->Ptr[SubPtr->Length] = '\0'; return *SubPtr; } int String::GetLength() const { return Length; } ostream &operator >(istream &Input, String &S) { char Temp[100]; Input >> setw(100) >> Temp; S = Temp; return Input; } int main() { String S1("happy"), S2(" birthday"), S3; cout << "S1 is \"" << S1 << "\"; S2 is \"" << S2 << "\"; S3 is \"" << S3 << '\"' << endl << "The results of comparing S2 and S1:" Trang 44
  45. LP TRÌNH H NG I T NG V I C++ S1 yields " S1) = S1 yields " = S1) << endl << "S2 <= S1 yields " << (S2 <= S1) << endl; cout << "Testing !S3:" << endl; if (!S3) { cout << "S3 is empty; assigning S1 to S3;" << endl; S3 = S1; cout << "S3 is \"" << S3 << "\"" << endl; } cout << "S1 += S2 yields S1 = "; S1 += S2; cout << S1 << endl; cout << "S1 += \" to you\" yields" << endl; S1 += " to you"; cout << "S1 = " << S1 << endl; cout << "The substring of S1 starting at" << endl << "location 0 fo r 14 characters, S1(0, 14), is: " << S1(0, 14) << endl; cout << "The substring of S1 starting at" << endl << "location 15, S1(15, 0), is: " << S1(15, 0) <<endl; // 0 is "to end of string" String *S4Ptr = new String(S1); cout << "*S4Ptr = " << *S4Ptr <<endl; cout << "assigning *S4Ptr to *S4Ptr" << endl; *S4Ptr = *S4Ptr; cout << "*S4Ptr = " << *S4Ptr << endl; delete S4Ptr; S1[0] = 'H'; S1[6] = 'B'; cout <<"S1 after S1[0] = 'H' and S1[6] = 'B' is: "<< S1 << endl; cout << "Attempt to ass ign 'd' to S1[30] yields:" << endl; S1[30] = 'd'; //Loi: Chi so vuot khoi mien!!! return 0; } 28. kt qu Trang 45
  46. LP TRÌNH H NG I T NG V I C++ D/ BÀI T ẬP T Ự GI ẢI Câu h ỏi tr ắc nghi ệm Câu 1: nh ngh a nào úng cho toán t nh p(>>) c a m t l p T a) istream& operator>>(istream&); b) istream& operator>>(istream); c) friend istream& operator>>(istream&, T&); d) friend istream& operator>>(istream&, T); Trang 46
  47. LP TRÌNH H NG I T NG V I C++ Câu 2 nh ngh a nào phù h p nh t cho toán t l y thành ph n([]) c a l p m ng A a) int operator [] (int) b) int& operator [] (int) c) friend int operator [] (A&, int) d) friend int& operator [] (A&, int) Câu 3: Ch ra cách nh ngh a toán t cho l p T b sai a) T operator-(T&) b) T operator-() c) T operator-() d) friend T opreator +(T&); e) T operator +(T&); Câu 4: Ch ra cách nh ngh a toán t cho l p T bíai a) T& operator ++() b) T operator ++(); c) T& operator++(int); d) T&operator++(float) Câu 5: Cho l p A class A { public: operator int (); }; A a; int i=a;(1) float f=a;(2) Ch ra dòng nào có l i a) Ch dòng 1 l i b) Ch dòng 2 l i c) C hai dòng u l i d) Không dòng nào l i Bài tâp Bài 1: To ki u d li u Date bi u di n ngày, tháng, n m. Cài t các toán t tính m t ngày tr ưc ho c sau m t ngày xác nh nào ó, tính kho ng cách thao ngày gi a hai ngày xác nh, tính th trong tu n c a ngày. Các toán t vào ra cho ngày. Bài 2: l ưu tr m t ma tr n i x ng thì không c n ô nh cho t t c các ph n t c a nó. Xây d ng l p bi u di n ma tr n i x ng có các toán t truy nh p t ng ph n t c a ma tr n. Ch s d ng l ưng b nh c n thi t l ưu ma tr n i x ng Bài 3 Xây d ng lp bi u di n các a th c v i các toán t c ng, tr , nhân, chia và o d u. nh ngh a toán t xu t k t xu t. Bài 4: Xây d ng m t l p map cho phép bi u di n m t ánh x t m t chu i kí t thành m t giá tr s nguyên. nh ngh a toán t [] cho l p có th s d ng ánh x theo cách nh ư [“abc”]->5 Trang 47
  48. LP TRÌNH H NG I T NG V I C++ Bài 5 Xây d ng m t l p bi u di n các vector n chi u v i các toán t c ng, tr , tích có hưng hai vector và tích vô h ưng m t vector v i m t s th c. nh ngh a toán t cho phép truy nh p các thành ph n c a vector. Trang 48
  49. LP TRÌNH H NG I T NG V I C++ Kü thuËt thõa kÕ MỤC TIÊU C ỦA BÀI NÀY GIÚP NG ƯỜI H ỌC  Cài t ưc s th a k  S d ng các thành ph n c a l p c ơ s  nh ngh a l i các hàm thành ph n  Truy n thông tin gi a các hàm thi t l p c a l p d n xu t và l p c ơ s  Các lo i d n xu t khác nhau và s thay i tr ng thái c a các thành ph n l p c ơ s.  S t ươ ng thích gi a các i t ưng c a l p d n xu t và l p c ơ s  Toán t gán và th a k  Hàm o và tính a hình A/ NH ẮC L ẠI LÝ THUY ẾT Th a k nâng cao kh n ng s d ng l i c a các on mã ch ươ ng trình. Ng ưi l p trình có th khai báo l p m i th a th a k d li u và hàm thành ph n t lp c ơ s ã ưc nh ngh a tr ưc ó. Ta g i l p m i là l p d n xu t. Trong ơ n th a k , m t l p ch có th có m t l p c ơ s . Trong a th a k cho phép mt l p là d n xu t c a nhi u l p Lp d n xu t th ưng b sung các thành ph n d li u và các hàm thành ph n trong nh ngh a, ta nói l p d n xu t c th h ơn so v i l p c ơ s và vì v y th ưng mô t m t lp các i t ưng có ph p vi h p h ơn l p c ơ s . Lp d n xut không có quy n truy nh p n các thành ph n private c a l p c ơ s . Tuy nhiên l p c ơ s có quy n truy xu t n các thành ph n công c ng và ưc b o v(proteced ). Hàm thi t l p c a l p d n xu t th ưng t ng g i các hàm thi t l p c a các l p c ơ s kh i t o giá tr cho các thành ph n trong l p c ơ s . Hàm hu b ưc g i theo th t ng ưc l i. Thu c tính truy nh p protected là m c trung gian gi a thu c tính public và private . Ch có các hàm thành ph n và hàm b n c a l p c ơ s và l p d n xu t có quy n truy xu t n các thành ph n protected ca l p c ơ s . Có th nh ngh a l i các thành ph n c a l p c ơ s trong l p d n xu t khi thành ó không còn phù h p trong l p d n xu t. Có th gán n i dung i t ưng l p d n xu t cho m t i t ưng lp c ơ s . M t con tr l p d n xu t có th chuy n i thành con tr l p c ơ s . Hàm o ưc khai báo v i t khoá virtual trong l p c ơ s . Các l p d n xu t có th ưa ra các cài t l i cho các hàm o c a l p c ơ s n u mu n, trái l i chúng có th s d ng nh ngh a ã nêu trong l p c ơ s . Nu hàm o ưc g i b ng cách tham chi u qua tên m t i t ưng thì tham chi u ó ưc xác nh d a trên l p c a i t ưng t ươ ng ng. Mt l p có hàm o không có nh ngh a(hàm o thu n tuý) ưc g i là l p tr u tưng. Các l p tr u t ưng không th dùng khai báo các i t ưng nh ưng có th khai báo con tr có ki u l p tr u t ưng. B. MỘT S Ố L ƯU Ý (Các l i th ưng g p, m t s thói quen l p trình t t )  Các l ỗi th ường g ặp  Cho con tr l p d n xu t ch n i t ưng l p c ơ s mà không m b o ch c ch n rng phiên b n m i c a hàm trong l p d n xu t c ng tr v cùng gái tr nh ư phiên bn c c a hàm.  Khai báo i t ưng c a l p tr u t ưng Trang 49
  50. LP TRÌNH H NG I T NG V I C++  Khai báo hàm thi t l p là hàm o.  M ột s ố thói quen l ập trình t ốt Khi th a k các kh n ng không c n thi t trong l p d n xu t, t t nh t nên nh ngh a li chúng. C/ BÀI T ẬP M ẪU Ví d  1: Gi s có các l p nh ư trong khai báo. Ch ra các l i sai cho các l nh c a ch ươ ng trình vi t d ưi ây. class A { public: void func(); }; class B: private class A { }; A a; B b; a.func(); A* pA =&b; B* pB=&a; Lời gi ải Li g i b.func() có l i b i vì l p B k th a l p A theo ch private . Do v y, t t c các thành ph n c a A s là private trong B, h ơn n a không th truy nh p vào m t thành ph n private . Mt i t ưng c a l p d n xu t c ng có th coi là i t ưng c a l p c ơ s . Do v y, khia báo A* pA=&b là hoàn toàn úng. Nh ưng iu ng ưc l i là không úng, nên khai báo B* pB=&a s gây l i khi biên d ch. Ví d ụ 2: Qu n lý h c viên CT4_2.CPP #include #include 29. class person_data { public: void getinfo(); void display(); person_data(); virtual ~person_data(); private : char name[25]; int roll_no; char sex; }; person_data::person_data() { } person_data::~person_data() { } void person_data::getinfo() { cout << "Ten: "; Trang 50
  51. LP TRÌNH H NG I T NG V I C++ cin>> name; cout >roll_no; cout > sex; } void person_data:: display() { cout >course_name; cout >semester; cout >grade; } void academics::display() { cout<<course_name<<"\t"; cout<<semester<<"\t"; cout<<grade<<"\t"; } // class stud_scholarship : public person_data, public academics { public: void getinfo(); void display(); stud_scholarship(); virtual ~stud_scholarship(); Trang 51
  52. LP TRÌNH H NG I T NG V I C++ private : float amount; }; stud_scholarship::stud_scholarship() { } stud_scholarship::~stud_scholarship() { } void stud_scholarship::getinfo() { person_data::getinfo(); academics::getinfo(); cout >amount; } void stud_scholarship::display() { person_data::display(); academics::display(); cout<<amount<<endl; } // int main() { stud_scholarship obj; cout<<"Nhap cac thong tin sau: "<<endl; obj.getinfo(); cout<<endl; cout<<"Ten So Gioi tinh Khoa Hoc ky Muc do"; cout<<" Amount"<<endl; obj.display(); return 0; } 30. D/ BÀI T ẬP T Ự GI ẢI Bài 1: Xây d ng l p Stack v i các thao tác c n thi t. T ó hãy d n xu t t l p Stack i m t s nguyên d ươ ng sang h m b t k . Bài 2: Hãy xây d ng các l p c n thi t trong phân c p hình 5.2 Bài 3: Hãy xây d ng các l p c n thi t trong phân c p hình 5.3 tính di n tích (ho c di n tích xung quanh) và th tích. Bài 4: Vi t m t phân c p k th a cho các l p Quadrilateral (hình t giác), Trapezoid (hình thang), Parallelogram (hình bình hành), Rectangle (hình ch nh t), và Square (hình vuông). Trong ó Quadrilateral là l p c ơ s c a phân c p. Trang 52