Giáo trình Lập trình nâng cao - Trần Uyên Trang

pdf 155 trang phuongnguyen 6991
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Lập trình nâng cao - Trần Uyên Trang", để 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:

  • pdfgiao_trinh_lap_trinh_nang_cao_tran_uyen_trang.pdf

Nội dung text: Giáo trình Lập trình nâng cao - Trần Uyên Trang

  1. Giáo trình Lập trình nâng cao
  2.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang Ch ng1 : GII THI U LP TRÌNH H NG I T NG I. LCH S PHÁT TRI N C A L P TRÌNH : 1. Lp trình tuy n tính :  Vi c l p trình cho các máy tính u tiên ph i vi t theo ngôn ng máy trong h nh phân nên m t nhi u th i gian khi ch y và th nghi m ch ng trình g r i.  Kh n ng s d ng l i các on ch ng trình: không có  Khi các kh n ng c a máy tính (MT) t ng: L p trình phát tri n t n gi n n ph c t p h n.  Các ti n nghi c n thi t cho vi c s d ng l i ch ng trình gc ban u hu nh không có trong các ngôn ng lp trình tuy n tính (LTTT) ban u. Khi c n làm công vi c này ng i ta ph i sao chép l i các ch ng trình g c, dn n ch ng trình dài ra. Nên vi c b o d ng, s a ch a khó, r t m t th i gian  D li u: Toàn c c, không có tính che d u d li u nên r t khó ki m soát 2. Lp trình có c u trúc :  Phân m nh v n l n thành các v n con c l p. T nh ng v n con này xây d ng thành th t c và hàm  D li u truy n gi a các th t c thông qua i s , ngoài ra nó có các d li u riêng mà các th t c bên ngoài ph m vi c a nó không th thâm nh p ti c 3. S tr u t ưng hoá ch c n ng :  Trong mt ch ng trình (CT) có c u trúc ch c n bi t th t c hay hàm ã cho làm c công vi c c th gì là , còn làm th nào mà công vi c ó l i th c hi n c thì không quan tr ng. M t khi th t c còn c tin cy thì nó có th dùng mà không c n bi t là nó ã ph i làm gì hoàn thành úng ch c n ng. iu này c g i là s tr u t ng hoá ch c n ng (functional abstraction), ây là n n t ng c a l p trình có c u trúc 4. Lp trình h ưng i t ưng (Object Oriented Programming):  Lp trình h ng i t ng (LTH T) là xây d ng trên n n t ng c a l p trình có c u trúc v i s tr u t ng hoá d li u.  S tr u t ng d li u (data abstraction) tác ng trên các d li u c ng t ng t nh s tr u t ng hoá ch c n ng ã làm trên ch c n ng. Khi s tr u t ng hoá d li u x y ra, các c u trúc d li u và các ph n t có th c s d ng mà không c n ý t i các chi ti t c th mà ng i ta xây dng.  S thay i c n b n là ch : 1 ch ng trình hng i t ng (HT) c thi t k xoay quanh d li u mà ta làm vi c trên nó h n là b n thân ch c n ng ch ng trình.
  3.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  LTH T s liên k t cu trúc d li u (CTDL) v i các thao tác theo cách mà chúng ta th ng ngh v th gi i xung quanh ó là: g n 1 hành ng c th v i 1 lo i i t ng nào ó. VD :  Ô tô thì có bánh xe, di chuy n c và h ng chúng thay i bng cách quay tay lái.  T ng t ta bi t cây là 1 lo i th c v t thân g và có lá  Ô tô không ph i là cây, cây không ph i là ô tô, v y ta có th k t lu n r ng iu th c hiên c v i ô tô thì không th th c hi n c v i cây. Th t hoang t ng khi i lái cây ho c t i n c cho ô tô nó l n lên  LTH T cho phép s d ng các quá trình suy ngh v th gi i quan vào d li u VD :  Mt m u tin thì có th c ra, thay i và l u tr ; còn m t s ph c thì có th dùng trong các phép toán. Tuy v y không th vi t mt s ph c vào t p tin làm m t m u tin nhân s c, và ng c li không th c ng hai m u tin nhân s l i v i nhau. M t ch ng trình LTH T s xác nh c im và hành vi c th c a các ki u d li u. iu ó cho phép chúng ta xác nh 1 cách chính xác chúng ta có th có c nh ng gì các ki u d li u khác nhau.  Chúng ta c ng luôn luôn liên h các khái ni m m i v i các khái ni m ã t n t i và l i có kh n ng suy lu n d a trên s liên h gi a các s v t . LTH T c ng làm vi c theo cách t ng t , cho phép ta xây d ng CTDL m i d a trên nh ng CTDL ang có mang theo nh ng tính n ng c a c u trúc n n mà chúng d a trên ó, trong khi v n thêm vào nh ng tính n ng m i – tính th a k (inheritance) II. NH NG THU T NG C A L P TRÌNH H NG I TNG : 1. Lp (class), i t ưng (object), ph ươ ng th c (method) :  LTH T cho phép t ch c d li u theo 1 cách t ng t nh các nhà sinh h c t ch c các loài th c v t khác nhau. Theo cách nói c a LTH T thì m i 1 loài th c v t ó s c g i là 1 l p-class  Mt lp là 1 b ng m u mô t các thông tin CTDL l n các công vi c c th c a các ph n t d li u  Mô t  Ch ra nó làm c cái gì ? – Hành vi trên nó  Mt ph n t mà c khai báo thu c 1 lp gi là 1 i t ng-Object Các hàm c nh ngh a h p l trên 1 lp gi là ph ng th c-Method và chúng là các hàm duy nh t có th x lý d li u c a các i t ng c a lp ó  Các CTDL dùng mô t 1 lp thì g i là các thu c tính-Properties VD : class complex {
  4.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang int real, imag // properties; void cong (complex c); // 1 void tru (complex c); // 2 void nhan (complex c); // 3 void chia (complex c); // 4 }; // 1,2,3,4: method complex a,b; // a,b: object  Mi m t i t ng thì có riêng 1 bn sao các ph n t d li u c a lp a:real imag b:real imag  Các ph ng th c nh ngh a trong 1 lp thì có th g i b i b t k 1 i tng nào. iu này g i là g i thông ip cho i t ng. Các thông ip thì ch ph thu c vào i t ng nh n, ngh a là i t ng nào nh n thông ip thì m i ph i làm theo thông ip ó. 2. Lp c ơ s (base class), l p d n xu t (derived class) :  Không gi ng nh các ki u d li u chu n s n, các l p có th s d ng các l p khác làm các viên g ch xây d ng cho mình.  Mt lp thì có th dùng xây d ng 1 lp mi. Lp ban u thì c gi là l p c s -base class. Còn lp m i g i là l p d n xu t-derived class. 3. Tính k th a (Inheritance) :  ó là kh n ng cho phép s d ng l i l p ã có s n xây d ng lp m i nh trên ã c p.  Vd: T l p Animals có th xây d ng các l p d n xu t (hay còn g i là lp con-subclass) t nó.  Lp d n xu t thì c k th a tt c các thu c tính-properties và ph ng th c-method c a l p c s , ngoài ra có th có các thu c tính m i và ph ng th c m i c a riêng nó. Animals Insects Mammals Reptiles Amphibians  Các l p Insects, Mammals, Reptiles, Amphibians là nh ng l p dn xu t t l p Animals chúng u có chung thu c tính c th a k t lp Animals là có hai m t, di chuy n c  Nh ng ngoài ra chúng v n có nh ng thu c tính riêng, ch ng h n Mammals thì ch s ng trên c n còn Amphibians thì v n có th sng c c trên c n l n d i n c
  5.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang 4. Tính a hình (Polymorphism) : VD : n ph m : Properties: Tên Method: c t vào, l y ra, tìm Sách : K th a t l p n ph m Properties : Tên, Tg, NXB Method: Tìm Báo : K th a t l p n ph m Properties : K ,Tên Method: Tìm  Do Báo l u tr khác Sách nên ph i vi t 2 th t c tìm khác nhau. Vi c tìm Sách và Báo là hoàn toàn khác nhau do ó có th nh ngh a 2 ph ng th c khác nhau. Tuy nhiên LTH T cung c p 1 kh n ng g i là tính a hình (polymorphism) gi i quy t v n này. Nó cho phép dùng 1 ph ng th c tìm ra c sách l n báo. Khi tìm sách, nó dùng ph ng th c tìm dành riêng cho sách, còn khi tìm báo, nó l i s d ng ph ng th c tìm t ng ng v i báo. Kt qu là ch c n m t tên ph ng th c duy nh t c dùng cho c hai công vi c ti n hành trên hai l p d n xu t có liên quan, m c dù vi c th c hi n c a ph ng th c ó thay i theo t ng l p.  Tính a hình thì d a trên s ràng bu c, ó là quá trình bu c 1 ph ng th c vi 1 hàm th c s . Khi các ph ng th c ki u a hình c s d ng, trình biên d ch s không xác nh hàm nào t ng ng v i ph ng th c s c g i. Hàm c th nào c g i là tu thu c vào lúc ch y. iu này c g i là s ràng bu c mu n, vì nó x y ra khi ch ng trình ang th c hi n.  S ràng bu c s m c ng c s d ng cho các ph ng th c không theo ki u a hình (còn g i là ph ng th c t nh). Lúc ó, khi biên d ch thì trình biên d ch ã bi t c th hàm nào c g i g n v i ph ng th c nào.
  6.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang Ch ng 2 : GI I THI U V NH NG IM M I C A C++ I. C++ LÀ GÌ ?  Là ngôn ng c xây d ng t ngôn ng C  Có t t c các tính n ng c a C  “Tôn tr ng” cú pháp c a C  Có b sung và c i ti n II. S KHÁC NHAU GI A C VÀ C++ 1. Ép ki u :  Trong C : (tenkieu)bien  Trong C++: tenkieu(bien)  Vd Tính công th c S = 2/1 + 3/2 + + (n+1)/n v i n là s nguyên d ng nh p t bàn phím, có th vi t: #include #include void main() { int n; printf(“\n So phan tu cua day N= “); scanf(“%d”,&n); float s=0.0; for (int i=1; i<=n; ++i) s += float(i+1)/float(i);//Ep kieu theo C++ printf(“S=%0.2f “,s); getch(); } 2. Ghi chú :  Trong C : /* */  Trong C++: /* */: ghi chú nhi u dòng // : ghi chú n cu i mt dòng 3. Khai báo :  Trong C++ : Ch c n khai báo tr c khi s d ng (m i n i) 4. Hng  Trong C : #define N 100; (Không bi t N là ki u gì)  Trong C++: const int N=100; (Cho bi t ki u c a N, ây g i là m t hng có ki u) 5. Toán t ph m vi ::  Trong C++ :: (b n d u ch m) Vd : int a=2; void main( ) {
  7.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang int a=3; printf(“ a ngoai:%d”,::a); (a=2) printf(“ a trong:%d”,a); (a=3) } 6. Vào ra trong C++ a. In d li u ra màn hình : Hàm printf() Toán t xu t: cout >bi n >> >>bi n Vd : Nh p 1 dãy không quá n ký t và ch a vào m ng h (ki u char) : cin.get(h,n); * Chú ý 1 : Toán t nh p cin >> s l i ký t chuy n dòng ‘\n’ trong b m, ký t này có th làm trôi ph ng th c cin.get Kh c ph c: dùng cin.ignore(1); Mc ích : b qua 1 ký t chuy n dòng * Chú ý 2 : s d ng các ph ng th c nói trên c n khai báo t p tiêu : #include 7. nh d ng khi in ra màn hình :  Quy nh r ng t i thi u là w v trí cho giá tr (nguyên,th c,chu i) c in trong toán t xu t ta dùng hàm: setw(w)  Hàm này c n t trong toán t xu t  Ch có hi u l c cho 1 giá tr c in g n nh t  Các giá tr in ti p theo có r ng t i thi u m c nh là 0 Vd: cout 8. Kiu li t kê : Ki u li t kê (enum) :  Tên vi t sau t khoá enum c xem là ki u li t kê và có th dùng khai báo, Vd: enum MAU {xanh, do, tim, vang};// n ki u MAU MAU m, dsm[10];// Khai báo các bi n, m ng ki u MAU  Các giá tr ki u li t kê là các s nguyên. Do ó có th th c hi n các phép tính trên các giá tr này, có th in, có th gán giá tr này cho bi n nguyên. Vd: MAU m1, m2; int n1, n2;
  8.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang m1= tim; m2= vang; n1 = m1; // n1= 2 n2 = m1+ m2; // n2= 5 printf (“\n %d”, m2); //in ra s 3  Không th gán tr c ti p 1 giá tr nguyên cho 1 bi n enum mà ph i dùng phép ép ki u, Vd: m1= 2; // l i m1= MAU(2); // úng 9. Cp phát và gii phóng b nh :  Trong C: p=(int) malloc(sizeof(int)); cp phát 1 vùng nh p=(int) calloc(n,sizeof(int)); cp phát n vùng nh free(p); gi i phóng b nh  Trong C++ : p= new int; cp phát 1 vùng nh p= new int[n]; cp phát n vùng nh delete p; Gi i phóng 10. i ki u tham chi u :  Trong C nh n k t qu c a hàm c n dùng i con tr . Làm cho vi c xây d ng c ng nh s d ng hàm khá phi n ph c.  Trong C++ a vào i ki u tham chi u (ging Pascal) dùng ch a k t qu c a hàm. Vi c t o l p và s d ng n gi n h n. Vd : Trong C : void swapint(int *a, int *b) { int temp= *a; *a = *b; *b = temp; } Gi hàm: swapint(&x, &y) Trong C++: void swapint (int &a, int &b) { int temp = a; a = b; b = temp; } Gi hàm: swapint (x, y) //không c n toán t &  Vy m t bi n tham chi u thì c xác nh b ng toán t & dùng tr c tên bi n gi ng nh toán t * dùng tr c con tr
  9.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  im khác nhau gi a 1 con tr ch n 1 bi n và 1 bi n tham chi u n nó là:  i v i con tr thì ph i dùng phép toán l y a ch  i v i bi n tham chi u thì không c n. 11. i có giá tr m c nh :  Trong nhi u tr ng h p ng i dùng vi t 1 l i g i hàm nh ng còn ch a bi t nên ch n giá tr nào cho các i. kh c ph c khó kh n này, C++ a ra gi i pháp i có giá tr m c nh. Khi xây d ng hàm, ta gán giá tr m c nh cho m t s i. Ng i dùng n u không cung c p giá tr cho các i này, thì hàm s dùng giá tr m c nh. Vd1: void delay ( int loops = 1000) { “L nh }; Gi: delay( ); // loops = 1000; delay(2000); // loops = 2000; Vd2: void test ( int a=100, int b=10; int c=1) { “L nh }; test( ); // l y các giá tr m c nh test(1,1,10); // a=1, b=1, c=10 test(10); // a=10, b,c m c nh test( ,10, ); // b=10, a,c m c nh test(20,10); // a=20, b=10, c m c nh 12. Hàm Inline :  Khi ch ng trình biên d ch nhìn th y m t l i g i hàm, nó th ng nh y n hàm ó. T i v trí cu i c a hàm nó s quay v l i l nh theo sau li g i hàm.  Có th l u trong không gian b nh nh ng l i t n thêm th i gian.  i v i nh ng hàm ng n kho ng m t n hai dòng l nh nên s dng inline  Mt hàm inline c vi t nh m t hàm bình th ng trong file ngu n nh ng biên d ch vào trong mã inline thay vì vào trong m t hàm. inline float converter(float dollars);  Hàm inline c trình bày nh m t th c th riêng bi t trong file ngu n nh ng khi ch ng trình c biên d ch, thân c a hàm th t s c chèn vào trong ch ng trình b t c âu m t l i g i hàm x y ra. Cách vi t hàm inline : Cách 1: inline[ki u tr v ] ( ); [ki u tr v ] ( )
  10.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang { // các câu l nh [return ] } Cách 2: inline[ki u tr v ] ( ) { // các câu l nh [return ] } * Hàm Inline : nh ng im c n l ưu ý  T khoá inline ph i xu t hi n tr c các l i g i hàm thì trình biên dch m i bi t c n x lý hàm theo ki u inline. Vd: #include int cong(int a, int b); void int main() { int tong=cong(1,2); print(“%i\n”, tong); } inline int cong(int a, int b) // tính t ng hai s { return a+b; } Ch ng trình biên d ch s thông báo l i vì ta ã khai báo và s d ng cong() nh m t hàm th c nh ng l i nh ngh a inline.  Bi vì mã c a hàm inline ph i c biên d ch tr c tr c khi nó c chen vào ch ng trình, cho nên ta luôn ph i nh ngh a hàm inline tr c khi tham kh o t i chúng.  T khoá inline th t s ch là m t g i ý cho ch ng trình biên d ch ch không ph i là m t l nh b t bu c. Th nh tho ng ch ng trình biên d ch (CTBD) s b qua inline và biên d ch hàm nh m t hàm bình th ng.  Ch ng hn n u có quá nhi u hàm inline, CTBD s không ch p nh n inline n a vì thi u b nh , ho c khi các hàm inline quá dài. 13. Hàm ch ng (Function Overloading) :  S d ng nh ngh a m t t p h p nh ng hàm c cho cùng tên và c b n cùng th c hi n nh ng thao tác nh nhau, nh ng s d ng danh sách i s khác nhau. void display(); // hàm display void display(const char*); void display(int one, int two); void display(float number);
  11.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Ch ng trình biên d ch s d ng ng c nh xác nh nh ngh a nào c a m t hàm c ch ng c g i: tu thu c vào s và ki u c a nh ng i s c cung c p trong l i g i.  Ch nh ng hàm mà c b n th c hi n cùng m t tác v , trên nh ng tp h p d li u khác nhau m i c ch ng. u im:  Rút ra vi c s d ng cùng m t tác v cho nh ng hàm có tên khác nhau.  Giúp hi u và g r i mã d dàng.  Duy trì mã d dàng h n. Overloading v i nh ng ki u d li u khác nhau  Ch ng trình biên d ch có th phân bi t nh ng hàm ch ng có cùng s l ng i s nh ng khác ki u. int square(int); float square(float); double square(double); Overloading v i s l ưng i s khác nhau int square(int); //khai b áo hàm int square(int,int,int); int asq = square(a) //g i hàm int bsq = square(x,y,z)  Gi hàm ph i t ng thích trên i s , ng c l i, n u không có hàm nào có s t ng thích ó thì ch ng trình biên d ch s thông báo l i.  Chú ý r ng ch ng trình biên d ch gi i quy t overloading tu thu c vào tr t t mà trong ó hàm c khai báo.  Ki u tr v c a hàm không c n xem xét. Hàm ch ng: Lu t ph m vi  Nguyên lý c a overloading c ch p nh n ch trong cùng ph m vi v i l i khai báo hàm class first{ public: void display(); }; class second{ public: void display(); }; void main() { first obj1; second obj2; obj1.display(); //không có hàm ch ng x y ra obj2.display(); }
  12.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Ph m vi c gi i h n nghiêm ng t i v i nh ng lp mà trong ó chúng c khai báo. 14. Ch ng toán t (Operator Overloading) :  Vi c dùng các phép toán thay cho 1 l i g i hàm rõ ràng làm ch ng trình ng n g n và sáng s a h n nhi u. Vd: th c hi n phép c ng 2 ma tr n ta vi t: C = A + B; rt g n v i toán h c  C++ cho phép dùng các phép toán chu n t tên cho các hàm (g i là nh ngh a ch ng toán t ).  ó là kh n ng k t h p m t toán t -operator ã t n t i v i m t hàm thành ph n và s d ng nó v i nh ng i t ng c a lp ch a nó nh là nh ng toán h ng-operands.  Nh ng bi u th c v i nh ng operators nh +, -, >, +=, = =, có th ch c áp d ng trên ki u d li u chu n nh int và float  Theo trên ta có ch ng toán t cho phép th c hi n nh ng câu l nh nh : if (obj1>obj2){ . . .} vi obj1 và obj2 là nh ng i t ng c a m t l p.  Thao tác c a vi c so sánh nh ng i t ng có th c nh ngh a trong m t hàm thành ph n và k t h p v i toán t so sánh-comparison operator.  Ch ng trình biên d ch có th phân bi t gi a nh ng toán t ch ng bng vi c ki m tra ki u d li u c a nh ng toán t ca nó.  Ch ng toán t là m t hình th c c a a hình. u im  Giúp cho ch ng trình d dàng c và g r i.  D dàng hi u r ng hai i t ng c c ng l i v i nhau và k t qu c gán cho i t ng th ba, n u ta s d ng cú pháp: obj3 = obj1 + obj2; thay vì, obj3.addobjects(obj1,obj2); nh ngh a các toán t ch ng  nh ngh a toán t ch ng ng i ta dùng cách vi t nh sau: ki u tr v operator ( ) { //các dòng l nh c a thân hàm toán t [ return ] } tên các phép toán chính là các bi n có ki u giá tr t ng ng v i ki u d li u m i, nó i di n cho các toán h ng c a toán t nh ngh a Vd: PS operator +(PS ps1, PS ps2); // n ch ng phép + hai phân s PS operator -(PS ps1, PS ps2); // đn ch ồng ph ép - hai ph ân s ố C 2 phép toán trên u là phép toán 2 toán h ng
  13.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang Ps1 óng vai trò là toán h ng 1, ps2 là toán h ng 2  Vi các phép toán > truy xu t 1 ki u d li u không chu n, nh ngh a ch ng c vi t theo ki u sau: ostream& operator ); istream& operator >>(istream& is, ); chính là ki u d li u m i c nh ngh a, nó có th là tên l p (class) s c nói n trong ch ng sau ho c tên 1 c u trúc (struct). Theo cách th c này i tng s c a n lu ng ra (lp ostream) ho c a n lung vào(lp istream) Khi dùng hàm toán t có 2 cách g i : C1 : Dùng nh 1 hàm thông th ng, t c là g i nó thông qua tên hàm. Vd: PS ps1, ps2, ps3, ps4, tg1, tg2; ps1=PS_set(3,4); ps2=PS_set(1,2); ps3=PS_set(5,7); ps4=PS_set(1,7); tg1 = operator+(ps3,ps4);// tính tng 2 phân s tg2 = operator-(ps1,ps2);// tính hi u 2 phân s C2 : dùng nh phép toán s h c chu n Vd: PS ps1, ps2, ps3, ps4, tg1, tg2; ps1= PS_set(3,4); ps2 = PS_set(1,2); ps3= PS_set(5,7); ps4 = PS_set(1,7); tg1 = ps3+ps4; tg2 = ps1-ps2; Nh n xét: Ta th y dùng nh cách 2 s t nhiên và n gi n h n cách 1 b i vì có th k t hp nhi u phép toán vi t các bi u th c ph c t p.
  14.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang BÀI T P CH Ơ NG 2 Bt1 : Cho mt dãy im trên m t ph ng, bi t to (x,y) c a t ng im. Vi t ch ng trình tìm m t c p im xa nhau nh t. Bt2 : Cho bi t h tên, im toán, lý, hoá c a N thí sinh. In ra danh sách thí sinh trúng tuy n khi bi t im chu n.Yêu c u in theo tr t t t ng d n c a t ng im. Bt3 : Cho m t ma tr n s th c c p m × n; vi t ch ng trình tìm ph n t l n nh t và ph n t nh nh t trên t ng hàng c a dãy s . Bt4: Vi t ch ng trình hi n xâu ký t b t k trên màn hình ho , t i v trí (x,y) và có màu m Bt5: Cho n hình ch nh t, bi t dài hai c nh c a t ng hình. Vi t ch ng trình tính và in ra chu vi và di n tích c a các hình. Bt6 : Cho bi t h tên, tu i, m c l ng và thu nh p c a N công nhân. Vi t ch ng trình in ra danh sách công nhân bao g m: s th t , h tên, tu i, m c l ng và thu nh p. Yêu c u in theo tr t t t ng d n c a tu i. Bt7: Tìm s ln nh t c a mt dãy s nguyên, dãy s th c.
  15.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang Ch ng 3: CÁC L P (Classes) I. NH NGH A L P (CLASS) : 1. Khái ni m v class :  Lp (class) là khái ni m trung tâm c a LTH T  Lp là s m r ng khái ni m c u trúc (struct) c a C và b n ghi (record) c a Pascal  Ngoài các thành ph n d li u nh c u trúc, l p còn ch a các thành ph n hàm, còn g i là ph ng th c (method) hay hàm thành viên (member function).  Cng gi ng nh c u trúc, l p có th xem nh 1 ki u d li u. Vì v y lp còn g i là ki u i t ng và c dùng khai báo các bi n, m ng i t ng  Trong ph n này s xây d ng các nh ngh a v lp, ph ng th c, ph m vi truy nh p, s d ng các thành ph n c a lp, l i g i các ph ng th c 2. nh ngh a l p (class) :  Lp (class) là nhóm c a nh ng i t ng (objects) có cùng chung thu c tính (properties) và có nh ng m i quan h chung  Thu t ng class là c vi t t t t nhóm t “class of objects” Vd: class of persons  Lp c nh ngh a nh sau: class tenlop { // Khai báo các thành ph n d li u;(properties) // Khai báo các ph ươ ng th c (methods) };  Minh ho i t ng và lp : 3. i t ưng (Object) :  Th hi n m t th c th trong th gi i th c  Mt khái ni m v i nh ng nh ngh a bên ngoài mà liên quan n v n chúng ta ang i m t.  i t ng ph c v hai m c ích:
  16.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Chúng giúp hi u c th gi i th c  Chúng cung c p m t n n t ng thi t th c cho s ng d ng ca máy tính  Mi i t ng có nh ng properties ho c nh ng nét c tr ng riêng ca nó mô t nh ng gì nó có ho c nó làm.  Xe c trong m t ng d ng giám sát giao thông  mouse và keyboard  Mt m u tin nhân s  Bng im liên quan n k thi  Nh ng s ph c  Minh ho : Nh ng i t ng khác nhau 4. Thu c tính (Property) :  Mt c tr ng c òi h i c a m t i t ng ho c m t th c th khi c trình bày trong m t lp c g i là m t thu c tính.  Thu c tính c a 1 lp có th là các bi n, m ng, con tr ki u chu n (int, float, long ) ho c ki u ngoài chu n ã c nh ngh a tr c (struct, union, class, )  Thu c tính c a 1 l p không th là ki u c a chính lp ó nh ng c phép là ki u con tr c a lp này: Vd: class A { A x; // Không ưc vì x có ki u l p A A *px;// ưc vì px là con tr ki u l p A }; 5. Ph ươ ng th c (Method) :  Mt hành ng c òi h i c a m t i t ng hay m t th c th khi c trình bày trong m t lp c g i là m t ph ng th c hay hàm thành ph n.  Trong m t lp polygon: "draw", "erase" và "move" là nh ng ví d c a nh ng ph ng th c–là m t ph n c a l p.  i t ng là m t “h p en" nh n và g i thông ip.  Hp en th c ch t ch a mã (dãy nh ng câu l nh c a máy tính) và d li u (thông tin mà nh ng câu l nh th c hi n trên nó).
  17.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang o Thông tin c truy n i và nh n l i t mi khu v c ho c b i nh ng b n ghi nh gi a các khu v c v i nhau ho c bi nh ng câu l nh b ng l i là nh ng thông ip gi a nh ng i t ng. o Nh ng thông ip này có th c biên d ch b i nh ng l i g i hàm trong ch ng trình  Ph ng th c có th c xây d ng t bên ngoài ho c bên trong nh ngh a lp. Thông th ng ph ng th c ng n vi t trong, ph ng th c dài vi t ngoài.  Giá tr tr v c a ph ng th c có th có ki u b t k (chu n ho c ngoài chu n).  Trong thân ph ng th c ca 1 l p có th s d ng:  Các thu c tính c a lp  Các ph ng th c ca lp  Các hàm xây d ng trong ch ng trình Vd: class complex { private: float real, imag; public: void set (float i=0.0, float j=0.0 complex &operator + (complex x); complex &operator – (complex x); void in ( ) { printf (“%f \t%f”, real, imag); } }; // nh ngh a các method complex complex:: &operator + (complex x) // complex th 2 ch rõ phép toán này thu c l p complex trong tr ng h p có nhi u l p. { real = real+x.real; imag = imag+x.imag; } void main( )
  18.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang { complex a, b, c, d; a.set(1,2); b.set(3,4); c = a + b; d = a – b; c.in ( ); d.in ( ); }; * Chú ý:  nh ngh a ph ng th c trong l p: Ki u tenpt (ds i) { // L nh }  nh ngh a ph ng th c ngoài l p Ki u tenlop:: tenpt (ds i) { // L nh }  Nu ph ng th c không có i ta v n ph i gi nguyên d u ( ). Vd: Xây d ng l p s nguyên: class dayso { private: int *p, n; public: void nhap( ); int max( ); int min( ); void sapxep( ); void in( ); }; void dayso:: nhap( ) { printf (“Nhap so pt:”); scantf (“%d”,&n); p= new int[n]; printf (“Nhap cac phan tu”); For (int *pa= p; pa m) m= *pa; return m; } void dayso::sapxep( )
  19.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang { int *px;*py,tg; for (px= p; px *px) { tg= *py; *py= *px; *px= tg; } } void dayso::in( ) { int *px; for (px= p; px< p+n; px++) printf (“%d \t”, *px); } void main( ) { dayso a; clrscr( ); a.nhap( ); printf (“so lon nhat: %d”,a.max( )); printf (“day ban dau”); a.in ( ); a.sapxep( ); printf (“day sau khi sap xep:”); a.in ( ); getch ( ); } Vd: Nh p danh sách h c sinh, nh p im chu n, và in ra s l ng h c sinh u D li u hs: + H tên + Tu i + im Ph ng th c: + Nh p + getD (tr l i im) + In class hocsinh { private: char ht[25]; int diem; int tuoi; public: void nhap( ); int getd { return diem; }
  20.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang void in( ); }; void hocsinh::nhap( ) { int t; fflush(stdin); puts(“Ho ten:”); gets(ht); printf(“tuoi:”); scanf(“%d”,&t); tuoi= t; printf(“diem:”); scanf(“%d”,&t); diem= t; } void hocsinh::in( ) { printf(“\n%s\t%d\t%d”,ht,tuoi, diem); } void main( ) { hocsinh ds[100]; int i,j,n; printf(“\n so hoc sinh”); scanf(“%d”, &n); printf(“Nhap hoc sinh”); for(i=0; i dc) ds[i].in( ); getch( ); } 6. Con tr this và i t ưng không t ưng minh (object implicit) :  T khoá this cho a ch c a i t ng mà c s d ng g i ph ng th c.  Bt c khi nào m t ph ng th c c g i, ch ng trình biên d ch s gán a ch c a i t ng mà g i ph ng th c ó cho con tr this.  Con tr this có th c s d ng gi ng nh b t c m t con tr nào khác n m t i t ng.  Có th c s d ng truy xu t nh ng thành ph n c a i t ng nó ch n b ng cách s d ng d u m i tên. this->age = 5; this->getdata(); class Person
  21.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang { private: int age; public: void display(); }; void Person :: display() { age = 25; cout age = 25; // age=25 cout age; // cout<<age } void main() { Person Jack; Jack.display(); } * Tham s ng v i i con tr this : Xét l i g i t i display( ) Person Jack; Jack.display();  Trong tr ng h p này tham s truy n cho con tr this chính là a ch ca Jack:
  22.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang this = &Jack Do ó: this->age ch ính l à Jack.age Nh v y câu l nh Jack.display(); s xu t ra d li u ca thu c tính c a i t ng Jack Vy ta có th rút ra k t lu n:  Tham s truy n cho i con tr this chính là a ch c a i t ng i kèm vi ph ng th c trong l i g i ph ng th c. 7. Toán t ph m vi (Scope resolution operator) :  Hàm có th c nh ngh a bên ngoài lp s d ng m t toán t ph m vi :: (hai d u hai ch m).  Cú pháp chung: Kieu_tra_ve tenlop ::ham_thanh_phan(danh sach doi so)  Ki u c a nh ng i s c a hàm thành ph n ph i phù h p chính xác vi ki u c khai báo trong lp ch nh.  Quan tr ng cho vi c nh ngh a nh ng hàm thành ph n bên ngoài s khai báo lp.  Toán t bên trái c a :: ph i là tên c a lp.  Có s t n t i c a toán t ph m vi m i nh n d ng c hàm nh là mt thành viên c a m t lp c th .  Cng c s d ng c p n tên c a m t bi n toàn c c (global variable) trong tr ng h p có m t bi n toàn c c và m t bi n c c b cùng tên.  Cú pháp th ng s d ng: :: bi n toàn c c  Trong vi c t tên bi n.  Nu hai bi n có nh ng m c ích khác nhau, tên c a chúng nên t khác nhau. Vd : int a=2; void main( ) { int a=3; printf(“ a ngoai:%d”,::a); (a=2) printf(“ a trong:%d”,a); (a=3) }  :: còn c dùng trong các nh ngh a hàm ngoài c a các ph ng th c c a các lp  Nó còn c dùng phân bi t các thành ph n trùng tên nhau c a các lp c s khác nhau. 8. Phm vi l p (class scope) :  Ph m vi:  Là ph n ch ng trình mà trong ó ta có th truy xu t n mt tên bi n nào ó  Hai ki u ph m vi th ng dùng trong C: o Global: bi n c khai báo bên ngoài m t hàm, có ph m vi toàn c c, có th c truy xu t t b t k ch nào trong ch ng trình
  23.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang o Local: bi n c khai báo bên trong m t hàm ho c m t kh i l nh, có th c truy xu t bên trong hàm ho c kh i l nh ó, bi n c c b có ph m vi a ph ng  Ph m vi l p:  ki m soát cách truy xu t t i các thành ph n d li u c ng nh method c a class.  Tt c các thành ph n c a m t class c coi là thu c v ph m vi c a class ó.  M t thành ph n b t k nào ó c a m t class có th tham kh o n b t k m t thành ph n nào khác c a cùng class ó  ây chính là m t ph n c a khái ni m bao b c (encapsulation). 9. Encapsulation:  Là vic truy xu t n m t i t ng ch thông qua nh ng thông ip ca nó, trong khi v n gi cho nh ng chi ti t private c g i d i d ng thông tin n.  Mt lp có nhi u thu c tính và ph ng th c. Ng i s d ng không cn thi t ph i truy xu t n t t c chúng.  Tt c s liên l c n i t ng c th c hi n thông qua thông ip.  Nu m t l p d n xu t có th truy xu t tr c ti p n các thành ph n private c a l p c s thì nh ng l p d n xu t t nó sau ó c ng có th truy xu t n nh ng thành ph n này. Kh n ng này s c lan truy n trên kh p các l p d n xu t trên cây th a k có th b c. iu này vi ph m tính bao b c d li u c a l p c s v kh n ng n thông tin.  Nh v y d li u s c t ch c sao cho các i t ng l p khác không th truy nh p c mà ch cho phép các hàm trong cùng l p ho c trong nh ng l p có quan h k th a v i nhau c quy n truy nh p.  Nguyên t c bao b c d li u ng n c m s truy nh p tr c ti p trong lp trình còn c g i là s che d u thông tin. Vd: class complex { private: double real; double imag; public: }; complex cong(complex c1, complex c2) // hàm t do { complex tg ; tg.real=c1.real+c2.real; tg.imag=c1.imag+c2.imag; return tg; }
  24.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang thì khi th c hi n, CTBD s a ra thông báo l i sau: ‘complex::real’ is not accessible ‘complex::imag’ is not accessible  s a ch a ta ph i khai báo l i hai thu c tính real và imag có c tính truy xu t là public.  Bi vì hàm cong(complex c1, complex c2) là mt hàm t do n m ngoài ph m vi l p nên trong ph m vi hàm không th truy nh p tr c ti p c n các thu c tính private c a l p complex .  Khi chúng ta bao b c úng cách, chúng ta s t c 2 m c ích sau:  Xây d ng c m t b c t ng không th thâm nh p c b o v nh ng on mã tránh nh ng h h i ng u nhiên do nh ng li nh mà vô tình chúng ta m c ph i.  Chúng ta c ng có th cô l p nh ng li n nh ng ph n nh ca mã khi n cho chúng d dàng h n tìm ki m và s a ch a.  Mc ích chính c a vi c này là ph i bao b c c u trúc d li u và ch c nng c a m t lp li, vi c truy xu t n c u trúc d li u c a các lp t bên ngoài lp ph i b gi i h n ho c tr nên không c n thi t n a ho c không th th c hi n c. 10. T khoá xác nh thu c tính truy xu t (access specifier): PRIVATE: & PUBLIC :  Khi khai báo các thành ph n c a 1 lp (ph ng th c & thu c tính) thì có th s d ng các t khoá PRIVATE: và PUBLIC: ch rõ ph m vi s d ng c a các thành ph n  Mc nh là PRIVATE:  Thành ph n c khai báo là PRIVATE: s d ng trong chính nó  Thành ph n c khai báo là PUBLIC: s d ng m i n i (c bên trong và bên ngoài lp), có th c truy xu t b i b t c m t hàm nào bên ngoài lp.  i v i 1 lp thì thu c tính th ng c khai báo là PRIVATE m b o tính che d u c a d li u.  Các ph ng th c th ng c khai báo là PUBLIC có th c s dng b t c m i n i trong ch ng trình.  D li u private không có s n bên ngoài lp i v i b t c ch ng trình nào  D li u private c a nh ng lp khác thì n và không có s n trong ph m vi truy xu t c a nh ng hàm c a lp này.
  25.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang 11. Hàm b n (Friend Function) : Hàm :  Mt l i khai báo hàm cho:  Tên c a hàm  Ki u c a giá tr tr v (n u có) b i hàm  S l ng và ki u c a i s c cung c p trong l i g i c a hàm  Mt l i khai báo hàm có th ho c không ch a tên i s  Có th g i m t hàm mà không ch rõ t t c nh ng i s c a nó. Hàm v i i s m c nh :  Li khai báo hàm ph i cung c p giá tr m c nh cho nh ng i s mà không c ch nh rõ.  Bt c khi nào có m t l i g i n hàm mà không xác nh rõ i s , ch ng trình s t ng gán giá tr b i nh ng tham s t s khai báo mc nh. void func(int = 1, int = 3, char = '*'); //khai báo //nguyên m u ho c void func(int num1,int num2 = 3,char ch = '*'); i s v i giá tr m c nh (default values)  Ch có giá tr uôi m i có th c m c nh. void func(int num1=2,int num2, char ch='+'); //li  Giá tr m c nh ph i có ki u chính xác, n u không ch ng trình biên dch s phát sinh l i.  Giá tr m c nh có th c cho trong nguyên m u hàm ho c trong ph n u c a nh ngh a hàm nh ng không trong c hai.  Giá tr m c nh th ng c cho trong khai báo nguyên m u h n là trong nh ngh a hàm . Ta có nh ng l i g i sau cho hàm func c khai báo trên:
  26.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang func(2,13,'+'); func(1); //giá tr m c nh cho i s th hai và th ba func(2,25); //giá tr m c nh cho i th ba func(); //giá tr m c nh cho t t c ba i func(2,,'+'); //không h p l  Nu ta b sót b t c m t i s nào trong kho ng gi a ch ng trình biên d ch s không bi t ta ang c p n cái gì và s phát sinh ra l i. u im :  i s m c nh s có ích n u ta mu n s d ng nh ng i, mà h u nh luôn luôn không thay i giá tr trong m t hàm.  Cng có ích khi sau khi m t ch ng trình c vi t, ng i l p trình quy t nh t ng kh n ng c a m t hàm b ng cách thêm vào m t i s .  Nh ng l i g i function ã t n ti có th ti p t c s d ng s l ng i s c , trong khi nh ng l i g i hàm m i có th s d ng nhi u h n Hàm b n (friend function) :  Giá tr c a d li u private không th c c ho c vi t b i nh ng hàm không ph i là thành viên.  Chúng ta c n m t ph ng ti n cho phép m t hàm truy xu t n nh ng ph n private c a m t lp mà không òi h i nó là thành viên.  Mt hàm không ph i là thành viên c cho phép truy xu t n nh ng ph n private c a m t lp c g i là bn c a lp ó.  Mt hàm c t o ra v i vai trò là bn c a m t lp b i m t l i khai báo friend trong lp ó: class person{ public: void getdata(); friend void display(person abc); }; void display(person abc) //friend function //kh ông c ó to án t :: {// mt vài mã }  T khoá friend không c l p l i trong nh ngh a hàm.  Nu cùng m t hàm c n truy xu t n nh ng i t ng t nh ng lp khác nhau thì vi c bi n nó thành bn c a nh ng lp khác nhau là cách h u hi u nh t. class Teacher; //khai báo tr ưc class Student { private: int st_data; public: void getstuddata(); friend void display(Student abc, Teacher xyz); }; class Teacher {
  27.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang private: int th_data; public: void getteachdata(); friend void display(Student abc, Teacher xyz); }; void display(Student abc, Teacher xyz) {// mt vài mã }  Khai báo tr c (forward declaration): M t class không th c cp n cho n khi nó ã c khai báo. Vì v y class Teacher ph i c khai báo tr c class Student.  Nh ng c tr ng c a hàm b n:  Mt hàm b n không có gì c bi t ngo i tr quy n truy xu t n thành ph n private c a m t class.  Hàm b n không có con tr this.  Khai báo friend có th c t ho c là trong ph n private ho c trong public c a m t lp.  nh ngh a m t hàm b n không òi h i tên lp cùng v i toán t ph m vi (::) tr c nó. u im :  Hàm b n cung c p m t m c c a s t do trong nh ng tu ch n thi t k giao di n.  Hàm thành ph n và hàm b n có nh ng c quy n nh nhau.  im khác nhau chính là m t hàm b n c g i d i d ng func(object), trong khi m t hàm thành ph n c g i d i d ng object.func() . Vd: C1: Dùng hàm thành ph n : class complex { private: float real, imag; public: complex cong(complex u2) { complex u; u.real = this->real + u2.real; u.imag = this->imag + u2.imag; return u; } }; Cách dùng: complex u, u1, u2; u = u1.cong(u2); C2: Dùng hàm b n : class complex { private: float real, imag;
  28.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang public: friend complex cong(complex u1, complex u2) { complex u; u.real = u1.real + u2.real; u.imag = u1.imag + u2.imag; return u; } }; Cách dùng: complex u, u1, u2; u = cong(u1, u2); 12. Lp b n (Friend classes) :  Khai báo m t hàm thành ph n n, m t vài hàm thành ph n ho c toàn b lp v i t cách là bn c a lp khác.  Vd c a m t hàm n v i t cách là bn class beta; //khai báo tr ưc class alpha{ private: int a_data; public: alpha(){a_data = 10;} void display(beta); }; class beta{ private: int b_data; public: beta(){b_data = 20;} friend void alpha::display(beta bb); }; void alpha::display(beta bb) { cout<<"\n data of beta ="<<bb.b_data; cout<<"\n data of alpha ="<<a_data; } void main(){ alpha a1; beta b1; a1.display(b1); }  Khi t t c ho c h u h t nh ng hàm c a m t lp c th ph i truy xu t n m t lp khác, ta có th cho lp ó có m t c quy n là lp b n. class beta; class alpha{ private: int data; public: friend class beta;//beta l à m t lp b n }; class beta{
  29.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang public: void display(alpha d) //có th truy xu t alpha {cout ; [return ; ] }; vi op là d u c a phép toán ưc ch ng  Gi ng các ph ng th c thông th ng, ph ng th c toán t có i s u tiên là con tr this  Du phép toán: (+,-,*, )  i v i các toán t 1 ngôi: Ta dùng con tr this làm i.  i v i các toán t nhi u ngôi: i th nh t dùng con tr this, các i sau ph i khai báo t ng minh. Vd: + Khai báo toán t m t ngôi class complex { private: double real; double imag; public: void set(double r, double i=0.0) { real = r; imag = i; }; complex operator-(); }; complex complex::operator-( ) { complex u; u.real = -this →real; u.imag = -this →imag; return u; } Cách dùng: complex u, v; v.set(3,-2)
  30.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang u = -v; + Khai báo toán t hai ngôi: class complex { private: double real; double imag; public: void set(double r, double i=0.0) { real = r; imag = i; }; complex operator+(complex x); }; complex complex::operator+(complex x) { complex u; u.real = this →real + x.real; u.imag = this →imag + x.imag; return u; } Cách dùng: complex p, q, r; p.set(3,-2); q.set(1,-2); r = p + q; 14. Ph ươ ng th c ki u inline  Cng nh các hàm khác, các hàm thành ph n c ng có th vi t theo ki u inline.  Có hai ki u vi t t o hàm thành ph n là inline:  t inline vào nh ngh a hàm thành ph n n m bên trong nh ngh a lp.  t inline vào nh ngh a hàm thành ph n n m bên ngoài nh ngh a lp. Vd: Xây d ng l i lp complex trên theo ki u dùng hàm thành ph n void set(double r, double i=0.0) là inline. C1: t inline trong lp complex class complex { private: double real; double imag; public: inline void set(double r, double i=0.0) { real = r; imag = i; }; complex operator+(complex x); }; C2: t inline ngoài lp complex
  31.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang class complex { private: double real; double imag; public: void set(double r, double i=0.0) complex operator+(complex x); }; // dinh nghia phuong thuc kieu inline inline void complex::set(double r, double i) { real = r; imag = i; };
  32.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang II.CU T (CONSTRUCTOR), HU T (DESTRUCTOR) VÀ CÁC V N LIÊN QUAN 1. Cu t (constructor) :  Cu t là m t hàm thành ph n c bi t cho s kh i t o t ng c a mt i t ng.  Có cùng tên v i lp ch a nó  Có th khai báo và nh ngh a cu t trong ph m vi lp, ho c có th khai báo chúng trong ph m vi lp và nh ngh a chúng bên ngoài nh bt c m t hàm thành ph n nào khác class username { public: username(); //constructor }; username::username() { }  Cu t c ng c g i khi m t i t ng t m th i ho c c c b c a lp c t o ra  Công d ng:  Cu t là 1 ph ng th c c a lp nh ng khá c bi t dùng to d ng 1 i t ng m i.  Ch ng trình d ch sau khi c p phát b nh cho i t ng s gi n cu t  Cu t th ng dùng kh i t o và gán giá tr cho các thu c tính và có th th c hi n 1 s công vi c khác nh m chu n b cho 1 i t ng m i. * Cách vi t cu t :  Cu t khác các ph ng th c thông th ng nh ng im sau:  Tên cu t trùng tên lp.  Cu t không có giá tr tr v  Không khai báo ki u cho cu t  Cu t ph i là public  S gi ng nhau gi a cu t và các ph ng th c thông th ng:  Có th xây d ng cu t bên trong và bên ngoài lp.  Cu t có th có ho c không i (default constructor )  Cu t có th có i ng m nh  Trong 1 lp thì có th có nhi u cu t (chúng cùng tên nh ng khác nhau b i) Vd: class date { private: int month, day, year; public: date() //cu t không i
  33.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang {day=1; month=1; year=2003;} date(int x) //ch có day ưc xác nh {day=x; month=1; year=2003;} date(int x, int y, int z) //day month year {day=x; month=y; year=z;} }; Vd: Xây d ng lp DIEM . Trong lp DIEM có cu t DIEM (int, int, int). Nh v y lp DIEM c vi t nh sau: class DIEM { private: int x,y;//tung ,hoành c a im ho int m; // màu c a im public: // nh ngh a cu t không i // gán x=0, y=0 và m=1 DIEM( ) { x=0; y=0; m=1; } // khai báo cu t có i và i m c nh, // nó ưc nh ngh a bên ngoài nh ngh a lp DIEM (int x1, int y1, int m1=13); // các ph ươ ng th c khác c a lp }; // nh ngh a cu t có i DIEM::DIEM(int x1, int y1, int m=13) { x=x1; y=y1; m=m1; } 2. Cu t sao chép (copy constructor) : Xét dòng khai báo sau: int a; int b=a; dòng l nh th 2: khai báo 1 bi n b và gán cho nó giá tr c a bi n a. T ng t : complex c1(9,3);// gi s l p complex có constructor 2 tham s complex c2=c1; Vi hai dòng l nh này hai i t ng c c1 và m i c2 có cùng m t n i dung  Khi m t i t ng c t o ra thì m t cu t c a lp t ng ng s c g i.  Cu t c g i khi khai báo và kh i t o n i dung m t i t ng m i thông qua m t i t ng khác g i là cu t sao chép  Nhi m v c a m t cu t sao chép là t o ra 1 i t ng m i gi ng h t i t ng ang có.
  34.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Ban u ta nh n th y cu t sao chép gi ng phép gán.  Th c ch t chúng có gi ng nhau không?  Phép gán th c hi n vi c sao chép n i dung t i t ng này sang i t ng khác, v y c hai i t ưng trong phép gán u ã t n t i  Cu t sao chép ng th i th c hi n hai nhi m v : o To i t ng m i o Sao chép n i dung t i t ng ã có sang i tng m i Vd: phép gán complex c1(9,3);//gi s l p complex có constructor //hai tham s complex c2; //gi s l p complex có constructor //không i c2=c1;  Hai i t ng c1,c2 c khai báo dòng l nh 1 và 2 có giá tr các thành ph n: c1.real=9; c1.imag=3; c2.real=0; c2.imag=0;  Khi th c hi n phép gán (dòng l nh 3) các i t ng c1,c2 ã t n t i  Phép gán ch có tác d ng làm cho các thành ph n c a c2 có giá tr b ng giá tr c a các thành ph n c1:  Vy khi ó: c2.real=9; c2.imag=3.  Trong khi ó n u dùng cu t sao chép ta có th thay 3 dòng lnh này b ng 2 dòng l nh sau: complex c1(9,3); complex c2=c1; ho c b ng: complex c1(9,3); complex c2(c1);  Tóm l i: Ta dùng cu t sao chép trong các tr ng h p:  Cn kh i t o i t ng m i có n i dung t ng t nh i tng ã có.  Khi c n truy n 1 i t ng cho hàm theo ki u tham tr  Hàm c n tr v m t i t ng nh m t o ra m t i t ng gi ng h t m t i t ng cùng lp ã có tr c ó.  Mt lp in hình gm có:  Khi m t lp X có m t thành ph n d li u ki u con tr , lp này nên có: cu t , hàm toán t gán, cu t sao chép and hu t . class X { X(some_value); //constructor
  35.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang X(const X&); //copy constructor X& operator=(const X&); //assignment ~X(); //destructor }; 3. Cu t sao chép m c nh (default copy constructor) : * Cu t sao chép m c nh :  T ng t nh cu t m c nh, cu t sao chép m c nh c t ng phát sinh n u chúng ta không nh ngh a. Nó c s d ng copy n i dung c a m t i t ng n m t i t ng mi trong su t quá trình xây d ng i t ng m i ó.  iu này nh m b o m tính úng n c a ch ng trình trong nh ng tr ng h p c n n cu t sao chép.  Vy khi ta khai báo các i t ng c a lp có ít nh t 2 hàm default có th c g i:  Cu t m c nh (default constructor)  Cu t sao chép m c nh (default copy constructor) * Công d ng c a m t cu t sao chép m c nh :  To i t ng m i  Gán giá tr c a các thành ph n trong i t ng c cho các thành ph n trong i t ng m i. Vd: Xây d ng lp complex không có cu t sao chép. Trong ch ng trình ki m tra, máy s t ng dùng cu t sao chép m c nh t o ra i t ng m i gi ng nh i t ng ã có tr c ó. #include #include class complex { private: double real; double imag; public: // cu t v i i m c nh complex(double r1=0,double i1=0) { real = r1; imag= i1; } void in( ) { cout<<“\n Phan thuc:”<< real<<“ Phan ao:”<<imag; } }; void main( ) // kim tra cu t sao chép m c nh {
  36.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang clrscr( ); complex c1(9,3); complex c2 = c1; c1.in( ); c2.in( ); cout ) { // các dòng l nh c a hàm nh m t o l p i t ưng mi this và gán giá tr c a các thành ph n d li u ca i t ưng m i b ng giá tr c a các thành ph n d li u c a i t ưng c }; D ng 2: tenlop (const tenlop & ) { //các dòng l nh c a hàm nh m t o l p i tưng m i this và gán giá tr c a các thành ph n d li u c a i t ưng m i b ng giá tr c a các thành ph n d li u c a i t ưng c }; trong ó, t khoá const nh m ng n c m m i thay i n i dung c a tham s truy n cho hàm. Ch ng trình sau s b sung thêm cu t sao chép vào l p complex. #include #include class complex { private: double real; double imag; public: // cau tu voi doi mac dinh. complex(double r1=0, double i1=0) { real = r1; imag = i1; };
  37.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang complex(const complex &c)// cau tu sao chep { this real=c.real; this imag=c.imag; getch( ); }; void in( ) { cout<<“\n Phan thuc:”<< real<<“ Phan ao:”<<imag; } }; void main()//kt cau tu sao chep { clrscr( ); complex c1(9,3); complex c2=c1; c1.in( ); c2.in( ); cout<<“\n Dung cach 2:\n”; complex c3(c1); c1.in( ); c3.in( ); getch( ); }  Trong ch ng trình này ta ã xây d ng cu t sao chép theo d ng 2.  Ch ng trình còn minh ho cách dùng cu t sao chép theo c hai dng.  T hai ch ng trình xây d ng lp complex nh trên ta nh n th y i vi tr ng h p này không c n xây d ng cu t sao chép t ng minh mà ch c n dùng cu t sao chép m c nh là .  Vy t i sao và khi nào c n xây d ng m t cu t sao chép t ưng minh  i v i các lp không có các thành ph n d li u ki u con tr ho c ki u tham chi u thì ch c n dùng cu t sao chép mc nh là .  Khi các class có các thành ph n d li u ki u con tr ho c tham chi u thì cu t sao chép m c nh ch a áp ng các yêu c u vì nó s gây ra vi c s d ng chung m t s vùng nh c a i t ng m i t o và i t ng c .(quá trình copy byte by byte s copy m t con tr t i t ng này n i tng khác và chúng cùng ch n m t a ch trong b nh )  Chính iu này d n n s nh p nh ng d li u gi a các i tng m i và i t ng c , gây ra các l i d li u không lng tr c c khi x lý. 5. Hu t (Destructor) * Công d ng:
  38.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Hu t là hàm thành ph n c a lp, c g i m t cách t ng khi mt i t ng b hu b  Có cùng tên v i lp  Hu t c g i trong các tr ng h p sau:  Khi thoát kh i hàm ho c ph ng th c, lúc ó c n ph i gi i phóng các bi n, m ng c c b  Khi th c hi n các hàm toán t , vd: +,-, ho c hàm gi i phóng b nh nh delete, free * Cách vi t hu t :  Gi ng nh cu t , hu t không có ki u và không có giá tr tr v .  Hu t không có i s  Hu t c ng là thành ph n public c a class.  Hu t c vi t theo m u sau: ~tenlop( ) Vd: Hu t c a l p s ph c complex có th c vi t nh sau: class complex { public: ~complex( ) // Hu t { real=0; imag=0; } };  Công d ng ph bi n nh t c a hu t là hu vi c c p phát b nh mà ã c c p phát cho i t ng b i cu t s d ng toán t new . class String { private: char *str; public: String(char *s) //cu t { int length = strlen(s); str = new char[length+1]; strcpy(str,s); } ~String() //hu t {delete[] str;} }; 6. Cu t , hu t m c nh (default constructor, destructor) : * Cu t m c nh :
  39.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Nu lp không nh ngh a cu t thì ch ng trình d ch s cung c p 1 cu t m c nh không i và ch n thu n gán 0 vào t t c các byte ca các bi n th hi n c a các i t ng.  Trong th c t ít có ch ng trình nào s d ng cu t m c nh vì vi c kh i ng b ng 0 nh v y th ng ch a chu n b 1 i t ng làm vi c.  Nu lp có ít nh t 1 cu t thì cu t m c nh s không c phát sinh n a. Khi ó m i câu l nh xây d ng i t ng m i u g i n cu t ca lp. N u không tìm th y cu t c n g i thì ch ng trình s báo li.  Khi xây d ng cu t thì có th dùng chúng trong khai báo t o 1 i t ng ng th i gán cho các thu c tính c a i t ng các giá tr . Da vào các tham s trong khi khai báo trình biên d ch s bi t g i n cu t nào. Vd: class complex { private: float real, imag; public: void in( ) { cout<<“phan thuc:”<<real<<“phan ao:”<<imag; } complex(float i, float j) { real=i; imag=j; } }; void main( ) { complex a(1,2);//g i cu t có i: hp l a.in( ); getch( ); complex c; //không h p l c.in( ); getch( ); } Dòng l nh complex a(1,2); s g i cu t có i gán các thành ph n d li u c a i t ng khai báo a giá tr : a.real = 1 và a.imag = 2 Còn dòng l nh complex c s g i 1 cu t không i khai báo i t ng c, nh ng vì trong class ch a có cu t không i nên máy s báo l i.  Ta ph i xây d ng 1 cu t n a (cu t không i)
  40.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang complex ( ) { real=imag=0; }  Trong các tr ng h p khai báo mà không kh i t o giá tr ho c khai báo và kh i t o giá tr u có th s d ng c thì ng i ta c n xây dng ít nh t 2 cu t  Mt cu t không i  Mt cu t có i *Chú ý:  Nu mu n vi t 1 cu t duy nh t thì danh sách các i u ph i t giá tr m c nh. Vd: complex(float i=0, float j=0)  Nh v y ch ng trình trên s có 2 cách kh c ph c:  Cách 1: Dùng cu t có i m c nh.  Cách 2: Xây d ng thêm cu t không i. Ch ng trình s c s a nh sau: // s d ng cu t có i m c nh #include #include class complex { private: float real, imag; public: void in( ) { cout<<“phan thuc:”<<real<<“phan ao:”<<imag; } complex(float i=1, float j=0)//cu t voi //doi mac dinh. { real=i; imag=j; } }; void main( ) { clrscr( ); cout<<“dung cu t co doi \n”; complex a(1,2); // goi cu t co doi a.in( ); cout<<“\n dung cu t co doi mac dinh \n”; getch( ); complex c; // goi cu t co doi mac dinh c.in( ); getch( ); clrscr( );
  41.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang cout<<“\n dung cu t co doi mac dinh \n”; c=complex(9,9); // goi cu t co doi c.in( ); getch( ); } *Hu t m c nh (default destructor) :  Nu trong lp không có nh ngh a hu t thì hu t m c nh ( không làm gì c ) c phát sinh.  i v i nhi u lp không dùng bi n con tr và tham chi u thì dùng hu t m c nh là và không c n dùng hu t tng minh. 7. Toán t gán (Assignment operator) *Toán t gán m c nh (default assignment operator) :  Toán t gán (cho l p) là 1 tr ng h p c bi t so v i các toán t khác.  Nu trong lp ch a có nh ngh a m t ph ng th c toán t gán thì trình biên d ch s phát sinh 1 toán t gán m c nh th c hi n l nh gán 2 i t ng c a 1 lp Vd: V i l p complex ta có th vi t : complex c1(3,4),c2;// khai báo hai i t ưng s // ph c c1, c2 c2 = c1;  Th c ch t c a phép toán này là sao chép các giá tr c a các thành ph n d li u t i t ng c1 sang các thành ph n d li u t ng ng c a c2, t c là: c2.real = c1.real = 3; c2.imag = c1.imag = 4;  Trong a s các tr ng h p khi l p không có các thành ph n d li u ng (con tr hay tham chi u) thì toán t gán m c nh là .  Trong tr ng h p ng c l i thì toán t gán m c nh là không thích hp. i v i các l p này, khi th c hi n phép gán các i t ng, vi c sao chép s không liên quan n các vùng d li u ng ( ó là s sao chép b m t).  Nói cách khác, sau khi b gán các i t ng gán và b gán s có chung vùng d li u ng ch a thông tin. Do v y s gây ra các phi n toái khi qu n lý thông tin và tính “riêng t ” c a d li u các i t ng ã b vi ph m.
  42.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang Vd: Có 2 i t ng c a l p dt1,dt2 c a l p DT. C 2 i t ng này u có thành ph n d li u t nh là n và 1 con tr a ch n vùng nh c p phát ng ch a d li u v h s c a a th c. Nu th c hi n phép gán hai i t ng trên qua các dòng l nh: DT dt1, dt2; // khai báo 2 i t ưng dt1, dt2 dt1.nhap( ); // nh p d li u cho i t ưng dt1(gi // s dt1.n=5) dt2=dt1; // th c hi n gán  Th c t , phép gán trên ã c th c hi n qua các dòng l nh: dt2.n = dt1.n và dt2.a = dt1.a;  Do v y con tr dt2.a và dt1.a u cùng ch n 1 vùng nh ng.  iu này d n t i vi c n u thay i các thông tin ng trên dt1 thì cng làm thay i các thông tin ng trên dt2 và ng c l i.  ây là iu không mu n vì nó làm m t tính riêng t c a các i tng.  Chính vì v y ta c n xây d ng toán t gán t ng minh khi l p có các thành ph n d li u ng. *Cách vi t toán t gán :  Toán t gán c ng là 1 ph ng th c c a lp cho nên i th nh t ca toán t là con tr this bi u th i t ng ích và dùng m t i th hai t ng minh bi u th i t ng ngu n.  Vì trong thân c a toán t gán ph i làm vi c tr c ti p v i i t ng ngu n nên ki u i t ng minh nh t thi t ph i là ki u tham chi u.  Toán t gán có th có ho c không có giá tr tr v .  Nu không có giá tr tr v (void) thì khi vi t ch ng trình không c phép vi t câu l nh gán liên ti p nhi u i t ng nh : dt1=dt2=dt3;  Nu toán t gán tr v tham chi u (&) c a i t ng ngu n thì có th dùng toán t gán gán liên ti p nhi u i t ng.  Cách nh ngh a chung toán t gán c vi t theo m u: [void] [const tenlop &] operator= (const tenlop & i_t ưng_ngu n) { // l nh c p phát b nh ng cho
  43.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang // các thành ph n ng c a i // t ưng ích và các l nh gán giá tr // cho các thành ph n [return ; ] }; Vd: Xây d ng toán t gán cho l p DT theo hai cách: C1: void DT::operator=(const DT &dt) { n=dt.n; this a=new double[n+1]; if (dt.a==NULL) a=NULL; else for(int i=0;i<=n;i++) a[i]=dt.a[i]; } Vi toán t gán này ch cho phép gán i t ng ngu n cho m t i t ng ích. Nh v y câu l nh gán sau là sai: DT dt1,dt2,dt3; // khai báo dt1.nhap( ); // nh p thông tin cho dt1 dt2=dt3=dt1; // l nh gán sai C2: có th gán liên ti p các i t ng trên, toán t gán c a l p DT ph i c xây d ng l i nh sau: const DT &DT::operator=(const DT &dt) { n=dt.n; this →a=new double[n+1]; if (dt.a==NULL) a=NULL; else for(int i=0; i<=n; i++) a[i] = dt.a[i]; return dt; }; Vi cách vi t này, có th vi t 1 câu l nh gán i t ng ngu n cho nhi u i t ng ích. Vd: Các câu l nh sau là úng: DT dt1,dt2,dt3,dt4; // khai báo dt1.nhap( ); // nh p thông tin cho dt1 dt2=dt3=dt4=dt1; // l nh gán úng Vd: + Xây d ng l p HOCSINH qu n lý h c sinh thi. + Thông tin vào g m có: tên, im toán, im lý, im hoá + Thông tin ra là t ng im Xây d ng bài toán nh sau: + D li u: *ht là bi n ki u con tr kí t l u tr h tên c a thí sinh toan, ly, tong là các bi n th c l u tr im toán, im lý và t ng im ca thí sinh. + Ph ng th c: HOCSINH( ); // hàm t o không i c a l p HOCSINH . const HOCSINH &operator=(const HOCSINH &hs); // hàm nh ngh a toán t gán.
  44.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang ~ HOCSINH( ); // là hàm hu c a l p. void nhap( ); // là ph ng th c nh p thông tin cho h c sinh void in( ); // a các thông tin c a h c sinh ra màn hình. double getd( ); // l y t ng im c a thí sinh (vì các hàm không th truy nh p vào các thành ph n riêng c a l p). void hoanvi(HOCSINH &hs); // là ph ng th c chuy n i giá tr c a hai i t ng trong l p HOCSINH cho nhau. Ch ng trình có n i dung: + Nh p danh sách hs g m các thông tin: h tên h c sinh, im toán, im lý. + S p x p hs theo tr t t t ng im gi m d n + In ds h c sinh theo tr t t m i # include # include # include class HOCSINH { private: char *ht; double toan, ly, tong; public: HOCSINH( ) // hàm t o không i { ht = new char[25]; toan = 0; ly = 0; tong = 0; } ~ HOCSINH( ) { delete ht; } const HOCSINH &operator=(const HOCSINH &hs) { this tong = hs.tong; this toan=hs.toan; this ly = hs.ly; strcpy(this ht,hs.ht); } return *this; void nhap( ); void in( ) { cout<<“\n”<<ht<<“\t”<<toan<<“\t”<<ly<<“\t” <<tong;
  45.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang } void hoanvi(HOCSINH &hs) { HOCSINH tg = *this; *this = hs; hs = tg; } double getd( ) { return tong; } }; void HOCSINH:: nhap( ) { cout > ht; cout > toan; cout > ly; tong = toan + ly; }; void main( ) { HOCSINH *ds; int n; clrscr( ); cout >n; ds = new HOCSINH[n]; for (int i = 0; i<n; i++) ds[i].nhap( ); clrscr( ); cout<<“ ds hoc sinh thi:”; for (i = 0; i<n; i++) { ds[i].in( ); getch( ); clrscr( ); cout<<“\n ds hs theo thu tu sx giam dan cua diem:”; for (i=0; i<n; i++) for (int j = i+1; j<n; j++) if (ds[i].getd( )<ds[j].getd( )) ds[i].hoanvi(ds[j]); clrscr( ); cout<<“\n Ket qua:”; for(i=0; i<n; i++) {ds[i].in( ); } getch( ); delete ds; }
  46.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang 8. Hàm chuy n i (Conversion Functions)  Nh ng hàm thành ph n s d ng chuy n i nh ng i t ng n ho c t nh ng ki u d li u c b n và cho nh ng s chuy n i gi a nh ng i t ng c a nh ng lp khác nhau. class Converter{ private: int feet; float inches; public: Converter() // cu t không i { feet = 0; inches =0.0;} Converter(float metres) //cu t v i //m t i { float f; f= 3.28 * metres; feet = int(f); inches = 12 *(f-feet); } }; void main() { Converter d1 = 1.55;//dùng cu t th hai Converter d2; //dùng cu t th nh t d2 = 2.0; //dùng cu t th hai } * Ki u c ơ b n (basic) n ki u ng ưi s d ng nh ngh a (user-Defined) :  Khai báo c a i t ng d1 s d ng cu t th hai và gán giá tr 1.55.  Nó trình bày m t s chuy n i c a m t h ng ki u float n mt i t ng c a lp Converter. d2 = 2.0; cng s d ng cu t cho vi c gán m t h ng float n i t ng d2 .  Ch ng trình biên d ch u tiên s ki m tra m t hàm toán t cho toán t gán.  Nu toán t gán không c ch ng, thì nó s s d ng cu t th c hi n vi c chuy n i.  Nu cu t c ng không c nh ngh a ch ng trình biên dch s phát sinh l i. * User-Defined n Basic :  Ch ng trình biên d ch ph i c ch th rõ ràng n u m t i t ng ph i c chuy n i thành ki u d li u c b n.  Nh ng ch th này s c mã hoá trong m t hàm chuyn i và c nh ngh a nh m t thành ph n c a lp ó. operator float() {
  47.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang float f; f = inches/12; f+= float(feet); return (f/3.28); } Có th c s d ng nh sau, m = d2; ho c s d ng m t dòng l nh rõ ràng, m = float(d1);  Hàm chuy n i ti n hành ch ng toán t ép kiê .  Hàm chuy n i ch a t khoá operator và thay vì m t d u phép toán (operator symbol) nó s ch a ki u d li u.  Hàm chuy n i không nh ngh a ki u tr v (return type) c ng không nên có b t c m t i s nào. * Chuy n i gi a nh ng i t ưng :  Hàm chuy n i ph i c ch nh b i vì ch ng trình biên d ch không bi t gì v ki u ng i s d ng nh ngh a (user-defined).  Có th là m t hàm thành ph n c a lp ngu n (n m phía bên ph i ca toán t gán)  Ho c nó có th là m t hàm thành ph n c a lp ích (n m phía bên trái c a toán t gán). objectA = objectB; objectA: i t ng c a lp ích objectB: i t ng ca lp ngu n.  Chuy n i c a nh ng i t ng c a hai lp khác nhau có th th c hi n c v i:  Cu t m t i s (one_argument constructor) c nh ngh a trong lp ích.  Ho c m t hàm chuy n i (conversion function) c nh ngh a trong lp ngu n. Vd: class LFeet{ private: int feet; float inches; public: LFeet(){feet = 0; inches =0.0;}//Cu t 1 LFeet(int ft,float in) //Cu t 2 { feet = ft; inches = in; } }; class LMetres{ private: float metres; public: LMetres(){metres = 0.0;} //Cu t 1
  48.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang LMetres(float m) //Cu t 2 {metres = m;} }; void main() { LMetres dm1 = 1.0; LFeet df1; df1 = dm1; } Hàm chuy n i (conversion function) trong lp ngu n :  Hàm chuy n i trong lp ngu n chuy n i chi u dài t lp ngu n LMetres n lp ích Lfeet s nh sau: operator LFeet() //hàm chuy n i { float ffeet, inc; int ifeet; ffeet = 3.28*metres; ifeet = int(ffeet); inc = 12*(ffeet - ifeet); return LFeet(ifeet,inc); }  df1 = dm1; g i m t hàm chuy n i n. Cu t trong lp ích : LFeet::LFeet(LMetres dm)//cu t { float ffeet; ffeet = 3.28*dm.GetMetres(); feet = int(ffeet); inches = 12*(ffeet - feet); }  Cng c n ph i nh ngh a hàm thành ph n GetMetres() trong lp ngu n Lmetres : float LMetres::GetMetres() { return metres; } Bng cho chuy n i ki u Hàm trong l p Ki u c a Conversion Hàm trong lp ích ngu n basic n class Cu t class n basic Hàm chuy n i class n class Cu t Hàm chuy n i 9. Cu t và i t ưng thành ph n * L p bao và l p thành ph n
  49.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Nu m t l p có các thu c tính là các i t ng c a các l p khác thì c g i là l p bao.  Còn các l p có các i t ng là thu c tính c a l p bao thì c gi là l p thành ph n. class A; { private: int a1, a2; // các thành ph n d li u khác public: // các hàm thành ph n l p A } class B { private: int b1, b2; A b3; // thành ph n d li u c a B là // i t ưng c a A // các thành ph n d li u khác public: // các hàm thành ph n l p B }; Vy trong vd, ta có B: là l p bao A : là l p thành ph n c a B * Cu t c a l p bao :  Trong l p bao, các method không th truy c p c n các thu c tính c a các i t ng c a l p thành ph n.  Do ó ta ph i s d ng các cu t c a các l p thành ph n kh i gán cho các i t ng thành ph n c a l p bao khi xây d ng cu t lp bao.  Cách dùng cu t c a l p thành ph n kh i gán cho i t ng thành ph n c a l p bao c vi t theo m u sau: tên i t ưng( )  Mu này c vi t bên ngoài thân cu t c a l p bao trên dòng u tiên. C th h n cu t l p bao c nh ngh a theo d ng: tenlop(ds i):tên itưng1(ds giá tr 1), tên it ưngi(ds giá tr i) { //các câu l nh kh i gán các thành ph n //d li u riêng không ph i là i t ưng thành ph n }; * Chú ý :
  50.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Tên i t ng i chính là tên c a i t ng thành ph n trong l p bao  Du ngo c n sau tên i t ng luôn ph i có, ngay c khi danh sách giá tr bên trong là r ng  Các i t ng thành ph n n u mu n kh i t o b ng cu t không i có th b qua, không c n ph i li t kê trong cu t . Nói cách khác, các i t ng không c li t kê trên dòng u c a cu t c a l p bao u c kh i gán b ng cu t không i c a l p thành ph n.  Danh sách giá tr l y t danh sách i. D a vào danh sách giá tr , CTBD s bi t c n dùng hàm t o nào kh i gán cho i t ng. N u ds giá tr là r ng thì hàm t o không i s c s d ng. Vd: class A { private: int a, b; public: A( ) // cu t không i { a=0; b=0; } A(int a1, int b1) // cu t có i { a=a1; b=b1; } }; class B { private: double x, y, z; public: B( ) // cu t không i { x=y=z=0; } B(double x1, double y1, double z1) // cu t có i { x=x1; y=y1; z=z1; } }; class C {
  51.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang private: int m, n; A u, v; B p, r; public: C(int m1, int n1, int a1, int b1, double x1, double y1, double z1): u( ), v(a1, b1), r(x1, y1, z1) { m=m1; n=n1; } };  on ch ng trình trên mô t vi c xây d ng cu t c a l p bao C da trên cu t c a các l p thành ph n A và B.  Trong cu t l p C các i t ng thành ph n c kh i gán nh sau: u: c kh i gán b ng cu t không i c a l p A v: c kh i gán b ng cu t hai i c a l p A r: c kh i gán b ng cu t 3 i c a l p B p: không có m t c kh i gán b ng cu t không i c a l pB * S d ng các ph ươ ng th c c a l p thành ph n :  Trong l p bao s có th s d ng b t k m t ph ng th c nào c a i t ng thành ph n theo cách: tên it ưng.tênpt( ) Vd: class A { private: int a; public: A( ) { a=0 } A(int i) { a=i; } void in( ) { cout<<“a=“<<a } }; class B {
  52.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang private: int b; A x; public: B( ): x( ) { b=0; } B(int i, int j): x(i) { b=j; } void in( ) { x.in( ); cout<<“b=“<<b; } }; void main( ) { B z(10, 20); z.in( ); getch( ); }
  53.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang III.I T NG VÀ HÀM 1. Static member :  Trong 1 lp có th ch a các thành ph n t nh (static)  khai báo các thành ph n t nh này ch c n thêm vào dòng khai báo ca chúng t khoá u là static.  Có hai lo i thành ph n t nh :  D li u t nh (Static Data Members)  Ph ng th c t nh (Static Member Functions) Thành ph n d li u t nh (static data members) :  Có ích khi m i i t ng c a lp cùng chia s m t m c thông tin chung  Nu m t thành ph n d li u c a m t lp c nh ngh a là static, thì dù cho có bao nhiêu i t ngs i n a, chúng ta c ng ch c n t o ra m i mt thành ph n d li u ó cho lp.  static: c p phát 1 vùng nh c nh.  Ch hi n h u trong ph m vi c a lp, nh ng th i gian s ng c a nó xuyên su t toàn b ch ng trình. static kieu_du_lieu bien; Ví d : class race_cars { private: static int count: int car_number; char name[30]; public: race_cars(){count++;}//cu t t ng bi n count ~race_cars(){count ;}//hu t gi m count }; int race_cars::count;  Thành ph n d li u tnh nên c kh i t o tr c khi hàm main() b t u. Quy cách khai báo thành ph n d li u t nh : class { [private/ public]: static ; [public/ private]: }; Cách truy xu t thành ph n d li u t nh :
  54.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  C1: T ng t nh ki u d li u thông th ng: truy xu t thông qua tên i t ng và tên thành ph n d li u, chúng c k t h p v i nhau b i du . ho c d u ph thu c vào t ng lo i i t ng.  C2: thông qua tên lp và tên thành ph n d li u t nh, chúng c n i vi nhau thông qua phép toán ph m vi :: theo ki u: ::  Cách này xem là t t h n vì các thành ph n d li u t nh không g n v i 1 i t ng c th nào. Do ó C2 tr c quan h n C1.  Thành ph n d li u t nh ging nh nh ng thành ph n d li u khác.  Nu m t thành ph n t nh c khai báo là thu c tính private trong mt class, thì nh ng hàm không ph i là thành viên không th truy xu t c nó.  Nu nó c khai báo nh là public, thì b t c thành ph n nào c a lp c ng có th truy xu t c.  Thành ph n t nh có th tr thành m t d li u toàn c c (global) cho lp. Vd1 : class A { private: int x; static int ts; }; A u, v; Khi ó: u.x; v.x → 2 vùng nh khác nhau → u.x ≠ v.x u.ts; v.ts → cùng 1 vùng nh → u.ts = v.ts → Các thành ph n t nh là chung cho c l p Vd2: Xây d ng l p NGUOI nh sau: class NGUOI { private: float tn; //thu nh p t ng ng ưi static int tongsn; //t ng s ng ưicó trong //lp (s i t ưng) static float tongtn;//t ng thu nh p c a //các i t ưng public: };
  55.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang NGUOI nguoi1, nguoi2; Khi ó:  nguoi1.tn và nguoi2.tn s chi m 2 vùng nh khác nhau  nguoi1.tongtn và nguoi2.tongtn ch là 1 giá tr , chúng ch a chung trong 1 vùng nh c a class.  Thành ph n t nh tongtn t n t i ngay c khi các i t ng nguoi1 và nguoi2 ch a khai báo.  Vi c truy xu t t i hai thành ph n d li u tn và tongtn c ng khác nhau Vd: - N u vi t nguoi1.tn, nguoi2.tn thì s truy xu t t i thành ph n tn ca nguoi1 và t i thành ph n tn c a nguoi2 (truy xu t t i hai vùng nh ca hai i t ng) - N u vi t NGUOI::tongtn , nguoi1.tongtn ho c nguoi2.tongtn thì s truy xu t t i cùng 1 vùng nh là tongtn c a l p, chúng có tác d ng nh nhau và có th thay th nhau. Kh i t o giá tr cho thành ph n t nh: :: ; ho c :: = ; Vd: float NGUOI::tongtn;// kh i gán cho tongtn giá tr 0 float NGUOI::tongtn=10;// kh i gán cho tongtn giá // tr 10 int NGUOI::tongsn; // kh i gán cho tongsn giá tr 0 int NGUOI::tongsn=1; // kh i gán cho tongsn giá tr 1 Chú ý: Khi kh i gán giá tr thì thành ph n t nh ch a t n t i. Vd sau s minh ho iu này: #include #include #include #include #include class NGUOI { private: char maso[9], hoten[25]; float tn; static int tongsn; static float tongtn; public: static void in( ) { cout<<“\n tong so nguoi:”<<tongsn<<
  56.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang “tong thu nhap:” #include #include #include #include class NGUOI { private: char maso[9], hoten[25]; float tn; static int tongsn; static float tongtn; public: static void in( ) { cout<<“\n tong so nguoi:”<<tongsn<< “tong thu nhap:”<<tongtn; } }; int NGUOI::tongsn=0; float NGUOI::tongtn=0; void main( ) clrscr( ); { NGUOI::in( ); getch( ); } S d ng thành ph n d li u t nh khi nào:
  57.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Vi nh ng thu c tính c a lp có các th hi n chung trên m i i tng c a lp thì ng i ta ch n chúng là các thu c tính static. Vd: Trong m t gia ình, + M i ng i có riêng mã s , h tên, thu nh p , ó chính là các th hi n riêng ca m i ng i và chúng s là nh ng thành ph n d li u thông th ng c a l p NGUOI. + Thu c tính t ng s ng i và t ng thu nh p c a gia ình là các d li u chung cho c l p nên chúng c ch n là thu c tính static trong l p NGUOI. Bài tp: Thêm m i m t hoá n, xoá, s a. Ta luôn luôn bi t c t ng s hoá n và tng s ti n. V y 2 thành ph n d li u này, ta xây d ng là thành ph n d li u tnh. class HD { private: char *tenhang; float sotien; static int tshd; static double tstien; public: HD (char *tenhang1=NULL, float st=0.0) { strcpy(tenhang, tenhang1); ++tshd; // t ng lên 1 tstien+ =sotien; // cng d n thêm // t ng s ti n } ~HD( ) { tshd; tstien- =sotien; } void sua( ) { cout >sotien; tstien+ =sotien;//c ng s ti n v a sa //vào t ng s ti n } void in( ) { cout<<“Tong so hoa don:”<<tshd;
  58.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang cout<<“Tong so tien:”<<tstien; } int HD::tshd=0; double HD::tstien=0.0; void main( ) { HD h1, h2, h3; h1= new HD(“Rau”,10); h2= new HD(“Thit”,20); h3= new HD(“Cachua”,40); h2.in( ); getch( ); delete h2; h3.in( ); getch( ); h1.sua( ); h3.in( ); getch( ); Hàm thành ph n t nh (static member functions) :  Mt hàm thành ph n t nh có th th c hi n ch trên thành ph n d li u tnh c a lp.  Ho t ng v i ph m vi toàn c c i v i t t c các thành ph n c a lp ca nó mà không nh h ng n ph n còn l i c a ch ng trình.  Nó không có m t con tr this.  Có th s d ng m t hàm thành ph n t nh truy v n m t i t ng tìm ra nó là i t ng nào.  Có ích trong vi c g r i m t ch ng trình gi a nh ng tình hu ng khác nhau Vd: N u ta dùng câu l nh: NGUOI nguoi1, nguoi2; xét trên l p NGUOI ã xây d ng trong m c tr c thì g i hàm thành ph n t nh in( ) ta có th dùng m t trong các l nh sau: nguoi1.in( ); nguoi2.in( ); NGUOI::in( ); Vd: class alpha { private: static int count;//thành ph n d li u t nh public: alpha(){count++;}//cu t t ng bi n count static void display_count() //hàm thành ph n tnh { cout<<count; } }; void main()
  59.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang { alpha::display_count();//tr ưc khi b t c m t // i t ưng nào ưc t o alpha obj1,obj2, obj3; alpha::display_count(); //sau khi 3 i t ưng // ưc t o }  Th m chí khi không có i t ng nào c t o chúng ta v n có th tr c ti p g i thành ph n t nh s d ng tên c a lp và toán t ph m vi nh sau: alpha::display_count(); Các tính ch t c a hàm thành ph n t nh :  Hàm thành ph n t nh c ng gi ng nh các method thông th ng ch trong thân c a hàm thành ph n t nh có th truy c p t i các thành ph n d li u c a lp v i iu ki n các thành ph n này không ph i là c a i tng ch th this.  Hàm thành ph n t nh là chung cho c lp, nó không l thu c vào 1 i t ng c th nào, nó t n t i ngay c khi lp ch a có i t ng nào. Do ó, các ph ng th c t nh có th c g i cho dù các i t ng c a lp ó có kh i ng hay không ( c nh ngh a hay ch a c nh ngh a).  Mt hàm thành ph n t nh s không h liên h v i m t i t ng implicit nào xác nh. Vì không òi h i m t i t ng implicit nào, nên 1 hàm thành ph n c khai báo là static s không có con tr this.  Chính vì iu này nên không th dùng hàm thành ph n t nh truy xu t t i d li u c a i t ng ch th ( i t ng this) trong l i g i hàm thành ph n t nh (tr thành ph n d li u static). Vd: Nu ta cho thêm vào trong ph ng th c t nh in( ) c a l p NGUOI các dòng l nh in ra các thu c tính riêng ( maso, hoten và tn ) c a i tng ch th this thì s có ch ng trình sau: #include #include #include #include #include class NGUOI { private: char maso[9], hoten[25]; float tn; static int tongsn; static float tongtn; public: static void in( ) {
  60.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang cout<<“\n ma so:”<<maso<<“ho ten:”<<hoten<<“thu nhap:”<<tn; cout<<“\n tong so nguoi:”<<tongsn<< “tong thu nhap:”<<tongtn; } }; int NGUOI::tongsn=0; float NGUOI::tongtn=0; void main( ) clrscr( ); { NGUOI::in( ); getch( ); }  Nu ch y ch ng trình này thì ch ng trình d ch c a máy s thông báo l i: member maso cannot be used without an object member hoten cannot be used without an object member tn cannot be used without an object  Nh v y, ph ng th c không th truy xu t t i các thành ph n d li u ca i t ng ch th this. 2. Cp phát b nh ng (dynamic memory)  Mt i t ng c t o khi s nh ngh a nó xu t hi n trong ch ng trình và nó s b hu khi tên c a nó ra kh i ph m vi ho c gi i h n c a ch ng trình.  Có ích t o ra m t i t ng m i mà s ch t n t i lâu nh nó c n.  new t o ra nh ng i t ngs nh v y và toán t delete có th c s d ng phá hu chúng sau ó. * New :  Toán t new c s d ng t o m t không gian nh cho m t i tng c a m t class.  Cú pháp chung c a toán t new là: kieu_dl bien_con_tro = new kieu_dl; Ví d , int *p; // con tr ch n ki u integer float *f; // con tr ch n ki u float p = new int; // c p phát b nh cho integer f = new float; // c p phát b nh cho float  Nu g i n new thành công, nó s tr v m t con tr n không gian mà ã c c p phát.  Tr v 0 n u không gian không có s n ho c n u có m t vài l i c phát hi n. Vd: Student *stu_ptr; //con tr n m t i t ưng c a ki u Student stu_ptr = new Student;
  61.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang Toán t new t ng t nh hàm malloc() c s d ng trong C. * Delete :  i t ng c t o b i new t n t i cho n khi nó b hu hoàn toàn bi delete . delete pointer_variable;  Ví d v new và delete . int *ptr; ptr = new int; *ptr = 12; cout << *ptr; delete ptr;  Luôn gi thói quen t t là hãy delete b nh khi ta ã hoàn thành công vi c v i nó.  Hãy l u ý r ng chúng ta không c s d ng nh ng con tr ch n nh ng b nh mà ã b xoá. 3. Cp phát m ng :  Cp phát kh i g m nh ng m ng có chi u dài khác nhau ta c ng s mt k thu t t ng t . int *ptr; ptr = new int[100]; delete [] ptr;  Bt c khi nào ta c p phát m t m ng nh ng i t ng s d ng new , Ta ph i s d ng [ ] trong dòng delete .  CTBD s báo l i n u ta delete m t bi n c malloc'ed và nó c ng s báo l i n u ta free m t bi n c c p phát b i new . 4. Bi n, m ng i t ưng  Mt lp c xem nh m t ki u d li u(hay là 1 ki u i t ng) do ó có th khai báo bi n, m ng theo các ki u sau: tenlop tenbien(ds doi so); tenlop tenmang[kichco]; Vd: S d ng l p DIEM có th khai báo các bi n, m ng DIEM nh sau: DIEM d[21]; // Khai báo m ng d g m 21 ph n t DIEM d1, d2, d3; // Khai báo 3 i t ưng d1, d2, d3  Sau khi khai báo thì 1 bi n ho c 1 m ng ( i t ng) u c c p phát 1 vùng nh riêng ch a các thu c tính riêng c a chúng nh ng s không có vùng nh riêng ch a các ph ng th c. Các ph ng th c s c s d ng chung cho t t c các i t ng cùng l p. Trong vd trên : sizeof(d1)= sizeof(d2)=sizeof(d3)= 3*sizeof(int)=6 sizeof(d) = 21* 6 =126 truy nh p n thu c tính c a i t ưng thì ta vi t: tenbien.tenthuoctinh tenmang[chiso].tenthuoctinh (ten itưng.tenthuoctinh)
  62.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang Vd: V i vd trên, m i i t ng d1,d2,d3 và m i ph n t d[i] u có 3 thu c tính là x,y,z. truy nh p n thu c tính ta vi t nh sau: d1.x // thu c tính x c a obj d1 d2.x // thu c tính x c a obj d2 d3.y // thu c tính y c a obj d3 d[3].z // thu c tính z c a ph n t d[3] d1.x = 99 // gán 99 cho d1.x d2.y = d1.x // gán d1.x cho d2.y. g i n ph ươ ng th c thì ph i dùng : tênbien.tenpt( ) mang[ch s ].tenpt( ); Vd: d1.nhap( ); // nh p s li u vào các thành // ph n d1.x,d1.y,d1.z d[3].nhap( );//nh p s li u vào các thành // ph n d[3].x, d[3].y, d[3].z Vd: S d ng l p DIEM nh p 3 im, hi n r i n các im v a nh p. S d ng hàm dohoa( ) kh i ng ho #include #include #include class DIEM { private: int x,y,z; public: void nhap( ); void an( ); { putpixel(x,y,getbkcolor( )); } void hien( ); }; void DIEM::nhap( ) { cout >x>>y; cout >z; } void DIEM::hien( ) { int mauht; mauht= getcolor( );
  63.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang putpixel(x,y,z); setcolor(mauht); } void dohoa( ) { int mh, mode; mh=mode=0; initgraph(&mh, &mode, ‘’’’); } void main( ) { DIEM d1, d2, d3; d1.nhap( ); d2.nhap( ); d3.nhap( ); dohoa( ); setbkcolor(BLACK); d1.hien( ); d2.hien( ); d3.hien( ); getch( ); d1.an( ); d2.an( ); d3.an( ); getch( ); closegraph( ); } 5. Con tr i t ưng  Con tr i t ng dùng ch a a ch c a bi n, m ng i t ng. Nó c khai báo nh sau: tenlop *ten_con_tr ; Vd: dùng l p DIEM khai báo: DIEM *p1, *p2, *p3;// khai báo 3 con tr p1, // p2, p3. DIEM d1, d2; // khai báo 2 i t ưng d1, d2 DIEM d[20]; // khai báo m ng i t ưng  Ta có th th c hi n các câu l nh: p1= &d2; // p1 ch a a ch c a d2, hay p1 tr // ti d2 p2= d; // p2 tr t i u m ng d p3= new DIEM; // t o 1 i t ưng và ch a a // ch c a nó vào p3  s d ng thu c tính c a i t ng thông qua con tr , ta vi t nh sau: ten_contro →tenthuoctinh;  S d ng ph ng th c:
  64.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang ten_contro →tenpt( ); Con tr , i t ưng và m ng: A d[20]; A *p; p = d // p tr t i u m ng d Chú ý: Nu con tr i t ng ch a a ch u c a m ng ( tr vào u m ng i t ng) thì có th dùng tên con tr thay cho tên m ng. (dùng p[i].y thay cho d[i]) Theo trên ta th y: p1 →x và d2.x là nh ư nhau p2[i].y và d[i].y là nh ư nhau Tóm t t: Ta có quy t c sau  Quy t c s d ng thu c tính: s d ng thu c tính c a i t ng ta ph i dùng phép . ho c phép . Trong ch ng trình không cho phép vi t tên thu c tính 1 cách n c mà ph i i kèm tên i t ng ho c tên con tr theo các m u sau: tên_ i t ưng.tên thu c tính tên_contr →tên thu c tính tên_mng it ưng[ch s].tên thu c tính tên_contr [ch s].tên thu c tính truy nh p n các thành ph n c a i t ưng thì ta ph i dùng tên bi n ho c m ng tênbi n/tênm ng.tênthànhph n tênthànhph n có th là thu c tính ho c ph ng th c con tr →tênthànhph n Vd: Ch ng trình d i ây s d ng l p DIEM nh p 1 dãy di m, hi n th và n các im v a nh p. Ch ng trình dùng 1 con tr ki u DIEM và toán t new t o ra 1 dãy i t ng #include #include #include Class DIEM { private: int x,y,z; public: void nhap( ); void an( ); { putpixel(x,y,getbkcolor( )); } void hien( );
  65.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang }; void DIEM::nhap( ) { cout >x>>y; cout >z; } void DIEM::hien( ) { int mauht; mauht = getcolor( ); putpixel(x,y,z); setcolor(mauht); } void dohoa( ) { int mh, mode; mh = mode = 0; initgraph(&mh, &mode,””); } void main( ) { DIEM *p; int i, n; cout >n; p = new DIEM[n+1]; for(i=1; i<=n; ++i) p[i].nhap( ); dohoa( ); for(i=1; i<=n; ++i) p[i].hien( ); getch( ); for(i=1; i<=n; ++i) p[i].an( ); getch( ); closegraph( ); } 6. i t ưng h ng (Const object) Gi ng nh các ph n t d li u khác, m t i t ng có th c khai báo là hng b ng cách dùng t khoá const. Vd: class DIEM {
  66.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang private: int x, y; int m; public: DIEM() { x=y=m=0; } DIEM(int x1, int y1, int m1=15) { x=x1; y=y1; m=m1; } }; const DIEM d= DIEM(200,100); //Khai báo i t ưng hng  Khi khai báo c n s d ng các cu t kh i gán giá tr cho i t ng hng  Giá tr kh i t o có th là h ng, bi n, bi u th c, hàm.  Các ph ng th c có th s d ng cho các i t ng h ng là cu t và hu t . V lý thuy t, các i t ng h ng không th b thay i, mà ch c t o ra ho c hu b i.  Khi dùng m t method cho i t ng h ng thì CTBD s c nh báo: Non-const function called for const object  Tuy nhiên khi th c hi n ch ng trình n i dung các i t ng h ng vn b thay i. Vd: Ch ng trình sau s minh ho iu này Ph ng th c toán t ++ v n có th làm thay i i t ng h ng #include #include #include #include class PS { private: int t, m; public: PS() { t=m=0; } PS(int t1, int m1) { t=t1; m=m1; } PS operator++()
  67.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang { t +=m; return *this; } void in() { cout >t>>m; } }; void main() { int t1=-3, m1=5; const PS p=PS(abs(t1)+2, m1+2);// Khai bao // i t ưng hang clrscr(); p.in(); ++p; p.in(); getch(); }
  68.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang BÀI T P CH Ơ NG 3 Bt1 : Hãy xác nh l i, n u có, trong nh ng l i khai báo d i ây: int fn1(int, int = 0, char* = 0); int fn2(int = 0, int = 0, char*); int fn3(int = 0, int, char* = 0); Bt2: Xây dng m t l p g m các i t ng là các lý l ch. Vi t ch ng trình nh p và in hai lý l ch (hai i tng c a l p LY_LICH là nhanvien1, nhanvien2) Bt3: Vi t ch ng trình nh p ba im b t k (to ba im), v tam giác t o thành b i 3 im v a nh p và tính chu vi c a tam giác này. Bt4 : Nh p m t dãy hình ch nh t, tìm hình ch nh t có di n tích l n nh t và hình ch nh t có chu vi l n nh t. - Nh p m t dãy hình ch nh t - Tìm và in hình ch nh t có di n tích l n nh t và hình ch nh t có chu vi l n nh t. Bt5: Nh p dãy im b t k , tìm tam giác có di n tích l n nh t trong các tam giác t o ra b i các nh là các im v a nh p. - Nh p dãy các im - Tìm và in tam giác có di n tích l n nht Bt6 : Vi t ch ng trình qu n lý nhân s c a các khu ph trong thành ph , g m các ch c n ng: - Nh p d li u cho các thành viên ca gia ình trong khu ph - Sa i thông tin c a m t thành viên c a gia ình trong khu ph - In gia ình có ng i có tu i cao nh t và tu i th p nh t trong t ng khu ph Bt7 : Cho m t danh sách cán b g m các thông tin: mã s , h tên và thu nh p. Vi t ch ng trình in ra danh sách cán b v i các thông tin: mã s , h tên, thu nh p và cu i danh sách in ra t ng s cán b hi n có cùng t ng l ng c a h . Ch ng trình chính g m các ch c n ng c b n: - Nh p thông tin c a t ng cán b trong danh sách cán b - In danh sách cán b cùng thông tin v t ng s ng i và t ng thu nh p. Bt8 : Xây d ng l p ma tr n và l p vect. Trong các l p có xây d ng ph ng th c th c hi n phép toán nhân ma tr n v i vect (s d ng c u t , hu t ). Bt9 : Xây d ng l p HINH_TRON v i các thu c tính r (bán kính), m (màu hình tròn), x, y (v trí hi n th c a hình tròn trên màn hình), *pr (tr t i vùng nh ch a nh hình tròn), hien (=1: n u là tr ng thái hi n, =0: n u là tr ng thái n) Vi t ch ng trình t o ra các chuy n ng lên, xu ng c a các hình tròn. Bt10 : S d ng l i bài bt4 nh ng gi i quy t b ng cách dùng ph ng th c tnh.
  69.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang Ch ng 4 : S K TH A (Inheritance) I. KHÁI NI M : Th a k là m t trong b n nguyên t c c s c a LTH T. c bi t ây là c s cho vi c nâng cao kh n ng s d ng l i các b ph n c a ch ng trình, nh ó có th phát tri n, b sung nâng c p các ch ng trình và các lp ã c s d ng tr c ó. II. K TH A Ơ N (SINGLE INHERITANCE) 1. K th a ơ n :  K th a n là quá trình c a vi c t o ra nh ng lp m i t m t lp c s (base class) ã t n t i. Vd : Chúng ta hãy xem xét m t ch ng trình mà trong ó chúng ta ti n hành làm vi c v i nh ng ng i ang ph c v trong m t t ch c.  Mi m t lp con (subclass) c xem nh c d n xu t t lp Employee. Lp Employee c g i là lp c s (base class) và nh ng lp m i c t o ra c g i là lp d n xu t (derived class).
  70.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Trong m t lp có th b c, nh ng lp d n xu t th a k nh ng ph ng th c và bi n c a lp c s .  Chúng c ng có th có nh ng thu c tính và ph ng th c c a riêng chúng. Thu n l i  Thu n l i quan tr ng nh t: Kh n ng s d ng l i c a mã .  Mt lp c s c xây d ng mt l n, nó có th thích ng làm vi c trong nh ng tình hu ng khác nhau.  Kt qu c a kh n ng s d ng l i mã là s phát tri n c a th vi n l p (class libraries).  Mt th vi n l p bao g m d li u và ph ng th c c bao b c trong m t lp.  Dn xu t m t lp t m t lp ã t n t i cho phép nh ngh a l i hàm thành ph n c a lp c s và c ng c thêm vào nh ng thành ph n mi cho lp d n xu t.  Lp c s duy trì không thay i trong c quá trình. 2. Lp c ơ s và l p d n xu t :  S d n xu t (derivation) s c bi u di n b ng d u m i tên t lp dn xu t n lp c s .  Mi tên ch v h ng lp c s c hi u r ng lp d n xu t tham kh o n hàm và d li u trong lp c s , trong khi lp c s không truy xu t n lp d n xu t.  Khai báo m t lp d n xu t n gi n t ng t nh b t c m t lp bình th ng nào.  Chúng ta c ng ph i cho bi t tên c a lp c s . Vd, class Manager : public Employee  Bt c lp nào c ng có th c s d ng nh m t lp c s .  Mt lp c s có th c chia làm hai lo i :  c s tr c ti p (direct base)  c s gián ti p (indirect base) Lp c ơ s tr c ti p và không tr c ti p (direct và indirect base) :  Mt lp c s c g i là tr c ti p n u nó c c p trong danh sách c b n. Vd : class A { };
  71.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang class B : public A { }; // lp A là m t lp tr c ti p.  Mt lp không tr c ti p có th c vi t nh sau : class A { }; class B : public A { }; class C : public B { };// Có th c m r ng n m t s l ng c p tu ý. Lp d n xu t (derived class) :  nh ngh a lp d n xu t :  Trong nh ngh a lp d n xu t ph i li t kê c tên c a t t c các lp c s tr c ti p c a nó và nh ngh a này c vi t theo m u sau : class :[public/ protected/ private] [,[public/ protected/ private] , ] { // các thu c tính riêng c a lp d n xu t, // ó là các thành ph n d li u m i. // các ph ươ ng th c, nh ng hàm mi c a // lp d n xu t, ho c hàm, ph ươ ng th c // ưc nh ngh a l i };  T khoá [private/ public] dùng xác nh ki u th a k là private hay public.  Nu b qua không dùng các t khoá này thì máy ng m hi u là ki u th a k private. Kh n ng truy xu t (Accessibility) :  c th hi n khi m t hàm thành ph n ho c thành ph n d li u ca mt lp c s có th c s d ng b i nh ng i t ng c a lp d n xu t.  Nh ng thành ph n c a l p luôn có th c truy xu t b i nh ng hàm thành ph n trong ph m vi lp c a chúng, b t k nh ng thành ph n ó là private hay public.  Nh ng i t ng c nh ngh a bên ngoài lp có th truy xu t n nh ng thành ph n c a l p ch n u nh ng thành ph n ó là public. Vd : nu emp1 là m t i t ng c a lp Employee , và display() là m t hàm thành ph n c a Employee , thì trong main() dòng l nh emp1.display(); là h p l n u display() là public .  i t ng emp1 không th truy xu t n nh ng thành ph n private c a lp Employee . 3. Tham kh o và truy xu t nh ng thành ph n c a lp c ơ s :
  72.  LËp tr×nh chuyªn n©ng cao TrÇn Uyªn Trang  Vi th a k :  Nh ng thành ph n c a lp d n xu t có th truy xu t nh ng thành ph n c a lp c s n u nh ng thành ph n ó là public.  Nh ng thành ph n c a lp d n xu t không th truy xu t n nh ng thành ph n private c a lp c s . Ki u c a Inheritance  Mt lp d n xu t có th c khai báo v i m t trong các ch nh sau: public, private và protected. Th a k public và th a k private:  Trong ki u th a k private, t t c các thành ph n public c a lp c s c th a k trong lp d n xu t và tr thành các thành ph n private ca lp d n xu t.  Ngh a là nh ng i t ng c a lp d n xu t trong main() th m chí không th truy c p c n nh ng hàm thành ph n public c a lp c s.  Trong ki u th a k public, các thành ph n public c a lp c s c th a k trong lp d n xu t và tr thành các thành ph n public c a lp dn xu t. Nh v y nh ng i t ng c a lp d n xu t có th truy xu t n nh ng hàm thành ph n public c a lp c s .  Nh ng hàm trong lp d n xu t có th truy xu t n nh ng thành ph n protected và public trong lp c s .  i t ng c a lp d n xu t n m bên ngoài lp ho c trong main() không th truy xu t n nh ng thành ph n private hay protected c a lp c s . S khác nhau gi a lp d n xu t public và l p d n xu t private .  i t ng c a lp B, là l p c d n xu t public t A có th truy xu t n nh ng thành ph n public c a lp c s .  Tuy nhiên, i t ng c a lp C, là l p c d n xu t private t A, không th truy xu t n b t k thành ph n nào c a lp c s .  Function trong m t lp d n xu t protected có th truy xu t n nh ng thành ph n protected và public c a lp c s . Tuy nhiên, i t ng ca lp d n xu t (trong main( ) hay bên ngoài lp) không th truy xu t b t k thành ph n nào c a lp c s . Base class Public Private Protected members Inheritance Inheritance Inheritance Public Public Private Protected Protected Protected Private Protected Private Not accessible Not accessible Not accessible Vd : class A{ //lp c s private: int privA; protected: int protA; public: int pubA;