Hàmtạovàđốitượngthànhphần 8.1. Lớp bao, lớp thànhphần Một lớp có thuộc tính là đốitượng của lớp khác gọi là lớp bao, ví dụ: class A { private: int a, b; . } ; class B { private: double x, y, z; . } ; class C { private: int m, n; A u; B p, q; . } ; Trong vớ dụ trờn thỡ: C là lớp bao A, B là các lớp thànhphần (của C) 8.2. Hàmtạo của lớp bao + Chỳ ý là trong cỏc phương thức của lớp bao không cho phép truy nhập trực tiếp đến các thuộc tính của các đốitượng của các lớp thành phần. + Vỡ vậy, khi xõy dựng hàmtạo của lớp bao, phải sư dụng các hàmtạo của lớp thànhphần để khởi gán cho các đốitượngthànhphần của lớp bao. Ví dụ khi xây dựng hàmtạo của lớp C, cần dùng các hàmtạo của lớp A để khởi gán cho đốitượngthànhphần u và dùng các hàmtạo của lớp B để khởi gán cho các đốitượngthànhphần p, q. 8.3. Cách dùng hàmtạo của lớp thànhphần để xây dựng hàmtạo của lớp bao 196 + Để dùng hàmtạo (của lớp thành phần) khởi gán cho đốitưọngthànhphần của lớp bao, ta sử dụng mẫu: tên_đối_tượng(danh sách giá trị) + Cỏc mẫu trờn cần viết bờn ngoài thõn hàm tạo, ngay sau dũng đầu tiên. Nói một cách cụ thể hơn, hàmtạo sẽ có dạng: tên_lớp(danh sách đối) : tên_đối_tượng( danh sách giá trị), . tên_đối_tượng( danh sách giá trị) { // Các câu lệnh trong thân hàmtạo } Chỳ ý là các dấu ngoặc sau tên đốitượng luôn luôn phải có, ngay cả khi danh sách giá trị bên trong là rỗng. + Danh sách giá trị lấy từ danh sách đối. Dựa vào danh sách giá trị, Trỡnh biờn dịch sẽ biết cần dựng hàmtạo nào để khởi gán cho đối tượng. Nếu danh sách giá trị là rỗng thỡ hàmtạo khụng đối sẽ được sử dụng. + Các đốitượng muốn khởi gán bằng hàmtạo không đối có thể bỏ qua, không cần phải liệt kê trong hàm tạo. Nói cách khác: Các đốitượng không được liệt kê trên dũng đầu hàmtạo của lớp bao, đều được khởi gán bằng hàmtạo không đối của lớp thành phần. Ví dụ: class A { private: int a, b; public: A() { a=b=0; } A(int a1, int b1) { a = a1; b = b1; } . } ; class B { private: double x, y, z; 198 public: B() { x = y = z = 0.0 ; } B(double x1, double y1) { x = x1; y = y1; z = 0.0 ; } B(double x1, double y1, double z1) { x = x1; y = y1; z = z1 ; } . } ; class C { private: int m, n; A u, v; B p, q, r; public: C(int m1, int n1,int a1, int b1, double x1, double y1, double x2, double y2, double z2) : u(), v(a1,b1), q(x1,y1), r(x2,y2,z2) { m = m1 ; n = n1; } } ; Trong hàmtạo núi trờn của lớp C, thỡ cỏc đốitượngthànhphần được khởi gán như sau: u được khởi gán bằng hàmtạo không đối của lớp A v được khởi gán bằng hàmtạo 2 đối của lớp A q được khởi gán bằng hàmtạo 2 đối của lớp B r được khởi gán bằng hàmtạo 3 đối của lớp B p (không có mặt) được khởi gán bằng hàmtạo không đối của lớp B 8.4. Sử dụng các phương thức của lớp thànhphần Mặc dù lớp bao có các thànhphầnđối tượng, nhưng trong lớp bao lại không được phép truy nhập đến các thuộc tính của các đốitượng này. Vỡ vậy giải phỏp thụng thường là: + Trong các lớp thành phần, xây dựng sẵn các phương thức để có thể lấy ra các thuộc tính của lớp. + Trong lớp bao dùng các phương thức của lớp thànhphần để nhận các thuộc tính của các đốitượngthành viên cần dùng đến. 8.5. Các ví dụ Hai chương trỡnh dưới đây minh hoạ các điều đó nói trong các mục trên. Ví dụ 1: Trong ví dụ này xét 2 lớp: DIEM (Điểm) và DT (Đoạn thẳng) Lớp DIEM là lớp thànhphần của lớp DT //CT4_12.CPP // Thuoc tinh doituong #include <conio.h> #include <iostream.h> class DIEM { private: int x,y ; public: DIEM() { x=y=0; } DIEM(int x1, int y1) { x= x1; y=y1; } void in() { cout << "(" << x << "," << y << ")" ; } } ; class DT { private: DIEM d1, d2; int m; public: 200 DT() : d1(), d2() { m=0; } DT(int m1,int x1, int y1, int x2, int y2) : d1(x1,y1), d2(x2,y2) { m=m1; } DT(int m1,DIEM t1, DIEM t2) { m=m1; d1 = t1; d2 = t2; } void in() { cout << "\n Diem dau : "; d1.in(); cout << "\n Diem cuoi: "; d2.in(); cout << "\n Mau : " << m; } }; void main() { DT u, v(1,100,100,200,200), s(2,DIEM(300,300), DIEM(400,400)) ; clrscr(); u.in(); v.in(); s.in(); getch(); } Ví dụ 2: Trong ví dụ này xét 3 lớp: Diem (Điểm) DTron (Đường trũn) HTron (Hỡnh trũn) Lớp DTron có một lớp thànhphần là lớp Diem. Lớp HTron có 2 lớp thànhphần là lớp DTron và lớp Diem. 202 Trong lớp DTron đưa vào phương thức vẽ đường trũn. Trong lớp HTron đưa vào phương thức vẽ và tô mầu hỡnh trũn. Khi xây dựng phương thức của lớp bao cần sử dụng các phương thức của lớp thành phần. //CT4_13.CPP // Thuoc tinh doituong #include <conio.h> #include <iostream.h> #include <graphics.h> class Diem { private: int x,y ; public: Diem() { x=y=0; } Diem(int x1, int y1) { x= x1; y=y1; } int getx() { return x; } int gety() { return y; } } ; class DTron // Duong tron { private: Diem t ; // tam int r ; int m; public: DTron() { r=m=0; } DTron(int x1,int y1,int r1,int m1): t(x1,y1) { m=m1; r=r1; } int mau() { return m; } void ve() { setcolor(m); circle(t.getx(),t.gety(),r); } }; class HTron { private: DTron dt; Diem d; int m; public: HTron() { m=0; } HTron(int x1, int y1, int r1, int m1, int x, int y, int mt): dt(x1,y1,r1,m1), d(x,y) { m = mt; } void ve() { dt.ve(); setfillstyle(1,m); floodfill(d.getx(),d.gety(),dt.mau()); } } ; 204 void main() { int mh=0, mode=0; initgraph(&mh,&mode,""); setbkcolor(1); DTron dt(100,100,80,6); HTron ht(300,300,150,15,300,300,4); dt.ve(); ht.ve(); getch(); closegraph(); } . cho các đối tượng thành phần p, q. 8.3. Cách dùng hàm tạo của lớp thành phần để xây dựng hàm tạo của lớp bao 196 + Để dùng hàm tạo (của lớp thành phần) . tượng thành phần của lớp bao. Ví dụ khi xây dựng hàm tạo của lớp C, cần dùng các hàm tạo của lớp A để khởi gán cho đối tượng thành phần u và dùng các hàm tạo